Sequelize cambia el tipo de getter/setter con Typescript.
Versión de Sequelize: v6
Estoy utilizando Sequelize.define para definir modelos. Uno de los atributos se guarda como texto largo pero se utiliza como objeto en la capa de aplicación con getter y setter:
interface ModelNameAttributes {
modelId: string;
extras: string;
...
}
interface ModelNameCreationAttributes extends Optional<modelnameattributes, 'modelid'=""> {}
interface ModelNameInstance
extends Model<modelnameattributes, modelnamecreationattributes="">,
ModelNameAttributes {}
type ModelNameStatic = typeof Model
& { associate: (models: any) => void }
& { new(values?: Record<string, unknown="">, options?: BuildOptions): ModelNameInstance }
module.exports = (sequelize, DataTypes) => {
const ModelName = sequelize.define('ModelName', {
modelId: {
allowNull: false,
primaryKey: true,
type: DataTypes.UUID,
},
extras: {
type: DataTypes.TEXT('long'),
get: function (): {[key: string]: any} {
let val = this.getDataValue('extras');
return val && JSON.parse(val);
},
set: function (value: {[key: string]: any}): void {
this.setDataValue('extras', JSON.stringify(value));
},
},
...,
})
return ModelName;
});
Cuando intento crear un registro con:
const payload: ModelNameCreationAttributes = {
extras: { hello: 'hi' },
...
};
ModelName.create(payload, { transaction });
Obtengo una línea roja debajo de “extras” que dice:
Type '{ [key: string]: any; }' is not assignable to type 'string'.
¿Qué debo hacer? Muchas gracias.</string,></modelnameattributes,></modelnameattributes,>
davy.ai
El problema aquí es que el atributo
extras
está definido comostring
en la interfazModelNameAttributes
, y la interfazModelNameCreationAttributes
no lo sobrescribe. Para solucionar esto, puedes agregar una sobrescritura para el atributoextras
con el tipoRecord<string, any="">
(que coincide con el getter y setter):Con este cambio, deberías poder crear un registro con una carga útil como:
typescript
</string,></modelnameattributes,></string,>const payload: ModelNameCreationAttributes = {
extras: { hello: 'hi' },
...
};
ModelName.create(payload, { transaction });