如何从Sequelize的普通Schema中推断模型类型?
如何从Sequelize的普通Schema中推断模型类型?
当然可以!Sequelize从v6版本开始就提供了专门的类型工具,能帮你从模型定义里自动推断出精确的TypeScript类型,再也不用忍受any的模糊提示啦。我给你分享几种项目里亲测好用的实现方式:
方式一:类继承+手动声明属性(最推荐)
这种写法是Sequelize官方在TS项目里最推荐的,类型提示精准,还能轻松处理自动生成的字段(比如时间戳):
import { Model, DataTypes, sequelize } from './你的sequelize实例文件'; // 定义数据库中存在的用户属性类型 interface UserAttributes { id: number; name: string; email: string; } // 定义创建用户时的可选属性(比如自增id创建时不用传) interface UserCreationAttributes extends Omit<UserAttributes, 'id'> {} // 让User类继承Model,并关联上面两个接口 class User extends Model<UserAttributes, UserCreationAttributes> implements UserAttributes { // 用!告诉TS这些字段会在运行时被Sequelize自动初始化 public id!: number; public name!: string; public email!: string; // 如果开启了自动时间戳,加上这些只读字段 public readonly createdAt!: Date; public readonly updatedAt!: Date; } // 初始化模型Schema User.init({ name: DataTypes.STRING, email: DataTypes.STRING, }, { sequelize, modelName: 'User', });
这样写出来的User模型,不管是查询、创建还是更新操作,TS都会给你完整的类型提示,彻底告别any。
方式二:用内置工具自动推断属性
如果你不想手动写接口,Sequelize的InferAttributes和InferCreationAttributes工具类型能自动从模型类里推断属性,写法更简洁:
import { Model, DataTypes, sequelize, InferAttributes, InferCreationAttributes } from 'sequelize'; class User extends Model<InferAttributes<User>, InferCreationAttributes<User>> { // 只用declare声明字段,类型会自动从Schema推断 declare id: number; declare name: string; declare email: string; declare readonly createdAt: Date; declare readonly updatedAt: Date; } User.init({ name: DataTypes.STRING, email: DataTypes.STRING, }, { sequelize, modelName: 'User', });
这种方式省去了手动写接口的步骤,字段多的时候能省不少时间,类型精度也不打折。
方式三:适配你习惯的define写法
如果你还是偏好sequelize.define的写法,也能实现类型推断:
import { Model, DataTypes, sequelize, InferAttributes, InferCreationAttributes, ModelCtor } from 'sequelize'; // 先定义模型的类型别名 type UserModel = Model<InferAttributes<UserModel>, InferCreationAttributes<UserModel>>; // 定义模型时指定类型 const User: ModelCtor<UserModel> = sequelize.define('User', { name: DataTypes.STRING, email: DataTypes.STRING, });
不过这种方式的类型提示精度略逊于类继承写法,所以更推荐前两种。
小注意点
- 确保你的Sequelize版本是v6及以上,这些类型工具都是v6才新增的
- 自动生成的字段(比如id、createdAt)记得用
readonly标记,避免代码里误修改 - 要是你加了自定义的实例方法或钩子,也能在模型类里声明,TS会自动识别
内容来源于stack exchange
相关产品推荐
相关产品推荐

