TypeScript继承Sequelize Model类后无法调用CRUD方法问题
在TypeScript中使用Sequelize时继承Model类后找不到CRUD方法的问题
我在TypeScript里用Sequelize做ORM,创建了继承自Sequelize的Model类的UserEntity实体类,这个Model类包含所有CRUD方法。在UserEntity类里调用CRUD方法一切正常,WebStorm的智能提示也能识别这些方法;但在继承UserEntity的User类里调用this.create()时,方法却找不到或未定义。请问哪里出错了?
原代码示例
Class A: UserEntity
import sequelizeDatabase from "../sequelize/sequelize"; import { DataTypes, Model, Optional } from "sequelize"; export interface UserAttributes { id: number, name: string, password: string, rank: number, status: number, plan: number } export interface UserInput extends Optional<UserAttributes, "id">{} export interface UserOutput extends Required<UserAttributes>{} export class UserEntity extends Model<UserAttributes, UserInput> { declare id: number; declare name: string; declare password: string; declare rank: number; declare status: number; declare plan: number constructor() { super(); } public async init() { UserEntity.init({ id: { type: DataTypes.INTEGER.UNSIGNED, autoIncrement: true, primaryKey: true }, name: { type: DataTypes.STRING(75), }, password: { type: DataTypes.STRING(128), }, rank: { type: DataTypes.INTEGER.UNSIGNED }, status: { type: DataTypes.INTEGER.UNSIGNED }, plan: { type: DataTypes.STRING(25) } }, { sequelize: sequelizeDatabase, freezeTableName: true, timestamps: false }) UserEntity.sync().then(r => { console.log("UserEntity synced") }) } } UserEntity.create() // 此处能找到方法
Class B: User
import { UserEntity, UserInput, UserOutput, UserAttributes } from "./UserEntity"; class User extends UserEntity { constructor() { super(); } public async add(payload: Partial<UserAttributes>): Promise<UserOutput> { this.create() // 此处找不到方法 } }
问题原因与解决方法
核心问题
Sequelize的Model类中,create、findAll这类CRUD方法都是静态方法——它们属于类本身,而非类的实例。你在UserEntity里调用UserEntity.create()是正确的静态调用,但在子类User里用this.create(),是试图在实例对象上调用静态方法,自然会提示方法未定义。
另外你手动实现了constructor和实例化的init方法,这也破坏了SequelizeModel的内部逻辑,完全没必要。
修正后的代码
修正的UserEntity
import sequelizeDatabase from "../sequelize/sequelize"; import { DataTypes, Model, Optional } from "sequelize"; export interface UserAttributes { id: number; name: string; password: string; rank: number; status: number; plan: number; } export interface UserInput extends Optional<UserAttributes, "id"> {} export interface UserOutput extends Required<UserAttributes> {} export class UserEntity extends Model<UserAttributes, UserInput> { declare id: number; declare name: string; declare password: string; declare rank: number; declare status: number; declare plan: number; // 移除多余的构造函数,Sequelize会自动处理实例创建 // 将初始化改为静态方法 public static async initModel() { UserEntity.init({ id: { type: DataTypes.INTEGER.UNSIGNED, autoIncrement: true, primaryKey: true }, name: { type: DataTypes.STRING(75), }, password: { type: DataTypes.STRING(128), }, rank: { type: DataTypes.INTEGER.UNSIGNED }, status: { type: DataTypes.INTEGER.UNSIGNED }, plan: { type: DataTypes.STRING(25) } }, { sequelize: sequelizeDatabase, freezeTableName: true, timestamps: false }); await UserEntity.sync(); console.log("UserEntity synced"); } } // 静态调用初始化方法 UserEntity.initModel();
修正的User类
import { UserEntity, UserInput, UserOutput, UserAttributes } from "./UserEntity"; class User extends UserEntity { // 移除多余的构造函数 public async add(payload: Partial<UserAttributes>): Promise<UserOutput> { // 通过类本身调用静态的create方法 return UserEntity.create(payload as UserInput); // 如果想让子类也能独立使用,也可以用类型断言调用构造函数的静态方法 // return (this.constructor as typeof UserEntity).create(payload as UserInput); } }
关键注意点
- 永远不要手动覆盖Sequelize
Model的构造函数,它内部会处理实例的创建逻辑。 - CRUD方法都是静态方法,必须通过类本身调用,不能用实例
this调用。 - 模型的初始化逻辑要放在静态方法里,通过类名直接调用,不要做成实例方法。
内容的提问来源于stack exchange,提问作者Bas Kruithof
相关产品推荐
相关产品推荐

