默认 getter 不返回值,除非在 Sequelize 中使用 TypeScript 时使用 `getDataValue()`

Default getters not returning values unless `getDataValue()` is used when using TypeScript in Sequelize

使用 Model.Create 时,我没有从我的模型上的 getter 获取值。但是,如果我使用 Model.getDataValue()

,这些值会被 returned

示例:

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

我对文档和示例的理解是 应该 return 值。

使用 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,
    }
);

create returns Sequelize 具有元数据的模型实例,记录数据位于元数据内的嵌套对象内。 (尝试 console.log(created) 查看记录在 Sequelize 实例中的存储方式)

要获取原始记录数据,您需要 toJSON()

const user = created.toJSON();
console.info(user.id, user.firstname)

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

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

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 讨论中的 example 创建可重用函数:

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); 
  }