首页 > 解决方案 > 使用 Sequelize 关联时缺少属性错误

问题描述

我在 TypeScript 中使用 Sequelize 在 Express 中实现 API。使用关联 mixin 返回的值时,我遇到了与类型相关的错误。

这是我定义的数据模型的一部分:

export class User extends Model {
  id!: number;
  username!: string;
  email!: string;
  password!: string;
  active!: boolean;

  createdAt!: Date;
  updatedAt!: Date;
}

export class UserSession extends Model {
  token!: string;
  userId!: number;
  expiresAt!: Date;
  renewalHours!: number;

  getUser!: BelongsToGetAssociationMixin<User>;
}

这是我在会话期间尝试验证请求的方式(在 Express 中间件中):

UserSession.findOne({ where: { token: req.body.token }, include: [User] })
  .then(session => {
    if (session) {
      const now = moment();
      if (session.expiresAt > now.toDate()) {
        session.set('expiresAt',
                    now.add(session.renewalHours, 'hours').toDate());
        session.save();

        req.user = session.getUser();
        next();
      } else {
        session.destroy();
        res.status(400).json({ msg: 'Session expired' });
      }
    } else {
      res.status(403).json({ msg: 'Not logged in' });
    }
  });

UserSessionUservia相关联UserSession.belongsTo(User)(细节省略)。

具体线路

req.user = session.getUser();

从 TypeScript 产生以下错误:

 Type 'Bluebird<User>' is missing the following properties from type 'User': id, username, email, password, and 26 more.

req是快递Request。我在其中添加了一个user字段(出于 TypeScript 的目的),如下所示:

declare global {
  namespace Express {
    export interface Request {
      user?: User;
      session?: UserSession;
    }
  }
}

我知道 Sequelize 现在是基于 Bluebird Promise 框架构建的,所以我怀疑这与我的类型定义有关。似乎 TypeScript 认为它UserSession.getUser不会返回带有User' 属性的东西。为什么不?

标签: node.jstypescripttypessequelize.js

解决方案


正如预测的那样,这是对 Sequelize 的 mixin 函数工作方式的一个非常简单的误解。与 Sequelize 中的所有内容一样,它们当然是使用 Bluebird 的异步调用!因此,UserSession.getUser不会返回User,而是返回用户的 Promise。该行固定如下:

req.user = await session.getUser();

当然,将此功能标记为async. 这也可以使用session.getUser().then( ... ).


推荐阅读