使用Typescript在Sequelize模型中创建实例方法

时间:2019-02-01 11:52:06

标签: node.js typescript model sequelize.js

我想扩展一个Sequelize 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;
};

我希望User.prototype.verifyUser可以工作,但打字稿会抱怨。如何添加文字?

4 个答案:

答案 0 :(得分:0)

我看到的一个解决方案是在声明模型后强制键入。所以

refs/heads/pr1762

答案 1 :(得分:0)

在@Shadrech评论之后,我有另一种选择(不那么狡猾和抽象)。

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

使用模型:

sequelize.query("SELECT ...").then((user: UserInstance & UserModelInstanceMethods) => {
  user.verifyPassword(req.body.password) // <= from UserModelInstanceMethods
  user.getDataValue('name') // <= from UserInstance
})

答案 2 :(得分:0)

使用dataTypes: Sequelize.DataTypes

时出现以下错误
Cannot use namespace 'DataTypes' as a type

对于以后阅读本书的任何未来人来说,这些过去的答案似乎不再有效。

答案 3 :(得分:0)

第1步:

定义一个新类型,它将描述模型DefinedModel的定义。另外,接收通用的T可以从接口定义的数据库中获取响应。

第2步:

创建模型实例,以解析connection.define返回到我们的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);