在 TypeScript 中调用 Passport.serializeUser 时,如何输入提示用户参数?

bra*_*oar 6 node.js express typescript passport.js

使用 TypeScript,我正在使用 Express 和 Mongoose 编写 API,并且尝试使用 Passport 设置身份验证,但在尝试将序列化器函数传递给 Passport 时收到“属性不存在”错误。

根据文档,我需要调用passport.serializeUser一个函数,该函数接受我的用户对象并done使用该用户的 ID 进行调用。

我从 获取类型定义@types/passport声明文件将函数的参数user键入serializeUserExpress.User

serializeUser<TID>(fn: (user: Express.User, done: (err: any, id?: TID) => void) => void): void;
Run Code Online (Sandbox Code Playgroud)

但是Express.User- 也定义为@types/passport- 是一个空接口:

declare global {
    namespace Express {
        // tslint:disable-next-line:no-empty-interface
        interface AuthInfo {}
        // tslint:disable-next-line:no-empty-interface
        interface User {}
Run Code Online (Sandbox Code Playgroud)

这是我的序列化器。TypeScript 抱怨说Property '_id' does not exist on type 'User'.

passport.serializeUser((user, done) => {
  done(null, user._id);
});
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,我添加了类型定义,将该_id属性添加到 Express.User:

declare namespace Express {
  interface User {
    _id?: string;
  }
}
Run Code Online (Sandbox Code Playgroud)

这消除了 TypeScript 错误,但这似乎不是解决问题的正确方法。是否有不同的方法来提供不需要我重写Express.User类型定义的序列化器函数?

ura*_*way 10

@types/express 贡献者推荐了您所做的声明合并方式。您可以在此处了解他们如何serializerUser使用 TypeScript进行测试。

declare global {
  namespace Express {
    interface User {
      username: string;
      _id?: number;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

User另一种方法是每次使用回调函数时输入回调函数的参数:

type User = {
  _id?: number
}

passport.serializeUser((user: User, done) => {
  done(null, user._id);
});
Run Code Online (Sandbox Code Playgroud)

我认为声明合并是一种更聪明的方式。