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