Je souhaite étendre une classe Sequelize Model pour ajouter d'autres méthodes d'instance, mais le typographie continue de se plaindre que "La propriété 'prototype' n'existe pas sur le type 'Model'"
const MyModel = (sequelize: Sequelize.Sequelize, dataTypes: Sequelize.DataTypes) => {
const User = sequelize.define<Instance, Attribute>(
"users",
{
id: {
type: dataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
email: {
type: dataTypes.STRING
},
...
},
{
tableName: "users",
...
},
);
User.prototype.verifyUser = function(password: string) {
...
};
return User;
};
J'attends User.prototype.verifyUser pour fonctionner mais dactylographié se plaint. Comment ajouter aux typages?
3 Réponses :
Une solution que j'ai vue est où vous forcez le type après avoir déclaré le modèle. Donc
interface UserModelInstanceMethods extends Sequelize.Model<Instance, Attributes> {
prototype: {
verifyPassword: (password: string) => Promise<boolean>;
};
}
const MyModel = (sequelize: Sequelize.Sequelize, dataTypes: Sequelize.DataTypes) => {
const User = sequelize.define<Instance, Attribute>(
"users",
{
id: {
type: dataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
email: {
type: dataTypes.STRING
},
...
},
{
tableName: "users",
...
},
);
User.prototype.verifyUser = function(password: string) {
...
};
return User;
} as Sequelize.Model<Instance, Attributes> & UserModelInstanceMethods;
Suite au commentaire de @Shadrech, j'ai une alternative (moins hacky et abstraite).
sequelize.query("SELECT ...").then((user: UserInstance & UserModelInstanceMethods) => {
user.verifyPassword(req.body.password) // <= from UserModelInstanceMethods
user.getDataValue('name') // <= from UserInstance
})
Utilisation de votre modèle:
export interface UserAttributes {
...
}
export interface UserInstance extends Sequelize.Instance<UserAttributes>, UserAttributes {
}
interface UserModelInstanceMethods extends Sequelize.Model<UserInstance, UserAttributes> {
// Came to this question looking for a better approach to this
// You'll need root's definitions for invocation and prototype's for creation
verifyPassword: (password: string) => Promise<boolean>;
prototype: {
verifyPassword: (password: string) => Promise<boolean>;
};
}
const MyModel = (sequelize: Sequelize.Sequelize, dataTypes: Sequelize.DataTypes): UserModelInstanceMethods => {
const User = sequelize.define<UserInstance, UserAttributes>(
...
) as UserModelInstanceMethods;
User.prototype.verifyUser = function(password: string) {
...
};
return User;
}
Étape 1:
Définissez un nouveau type qui décrira la définition du modèle DefinedModel . De plus, recevez un T générique pour obtenir les réponses de la base de données définie par une interface.
Étape 2:
Créez une instance du modèle analysant le connection.define retour à notre DefinedModel.
// Step 0: Declarations
const connection: Sequelize = new Sequelize({...});
const modelName: string = '...';
const definition: ModelAttributes = {...};
const options: ModelOptions = {...};
interface MyInterface {...}; // Should describe table data
// Step 1
type DefinedModel<T> = typeof Model & {
new(values?: object, options?: BuildOptions): T;
}
// Step 2
const model: DefinedModel<Model> = <DefinedModel<Model>>connection.define(modelName, definition, options);
// Step 2 with Interface definition
const iModel: DefinedModel<MyInterface & Model> = <DefinedModel<MyInterface & Model>> connection.define(modelName, definition, options);