首页 > 解决方案 > 默认 getter 不返回值,除非在 Sequelize 中使用 TypeScript 时使用 `getDataValue()`

问题描述

使用Model.Create. 但是,如果我使用,则返回值Model.getDataValue()

例子:

const created = await User.create({
   id: '1',
   firstname: 'Darth'
});

console.info(created.id, created.firstname); // values are undefined

console.info(created.getDataValue('id'), created.getDataValue('firstname') // outputs correct values

我对文档和示例的理解是这应该返回值。

使用 TypeScript v4.0.3 和 Sequelize v6.3.5

型号定义:

export interface UserAttributes {
    id: string;
    firstname: string;

    createdAt?: Date;
    updatedAt?: Date;
}

export interface UserCreationAttributes extends Optional<UserAttributes, 'id'> {
}

export class User extends Model<UserAttributes, UserCreationAttributes> implements UserAttributes {
    public id: string;
    public firstname: string;

    // timestamps!
    public readonly createdAt!: Date;
    public readonly updatedAt!: Date;
}

User.init(
    {
        id: {
            type: DataTypes.UUIDV4,
            primaryKey: true,
        },
        firstname: {
            type: DataTypes.STRING(36),
            allowNull: true
        },

        createdAt: {
            type: DataTypes.DATE,
            allowNull: false,
            defaultValue: DataTypes.NOW,
        },
        updatedAt: {
            type: DataTypes.DATE,
            allowNull: false,
            defaultValue: DataTypes.NOW,
        }
    },
    {
        sequelize,
    }
);

标签: sequelize.js

解决方案


对于未来的读者:这是 babel 的一个问题。见问题 10579

在类上创建一个构造函数,如下所示:

export class User extends Model<UserAttributes, UserCreationAttributes> implements UserAttributes {
    public id: string;
    public firstname: string;
    ...

    constructor(values: any = {}, options: object = {}) {
        super(values, options)

        this.id = values.id
        this.firstname = values.firstname
        ...
    }
}

或根据 GitHub 讨论中的示例创建可重用函数:

export default function restoreSequelizeAttributesOnClass(newTarget, self: Model): void {
  Object.keys(newTarget.rawAttributes).forEach((propertyKey: keyof Model) => {
    Object.defineProperty(self, propertyKey, {
      get() {
        return self.getDataValue(propertyKey);
      },
      set(value) {
        self.setDataValue(propertyKey, value);
      },
    });
  });
}

并从您的构造函数中调用:

  constructor(...args) {
    super(...args);

    // hydrate the getters
    restoreSequelizeAttributesOnClass(new.target, this); 
  }

推荐阅读