Sequelize使用.d.ts定义模型类型,Model.create()属性全为可选?
Sequelize模型类型定义:Model.create()属性全为可选的解决办法
问题场景
在JavaScript项目中使用.d.ts文件编写Sequelize模型的类型定义时,大部分功能正常,但调用Model.create()时,所有属性都被标记为可选,不符合预期(其中some_required_property应为必填项)。
现有代码
index.d.ts
interface MyModelSchema extends Model<InferAttributes<MyModelSchema>, InferCreationAttributes<MyModelSchema>> { id: CreationOptional<string>; some_required_property: number; some_optional_property?: number; } type MyModel = ModelStatic<MyModelSchema>; declare const MyModel: MyModel;
index.js
// 文档上的属性已正确标记为必填,但此处所有属性均显示为可选 const document = MyModel.create({ // 无强制提示需要传入some_required_property });
解决方法
问题根源是InferCreationAttributes的自动推断未正确识别必填属性,可通过以下两种方案修正:
方案1:显式区分实例属性与创建属性
通过拆分实例属性和创建属性的类型定义,让Sequelize的类型系统明确识别必填项:
import { Model, ModelStatic, CreationOptional } from 'sequelize'; // 定义模型实例的完整属性(包括自动生成的id) interface MyModelAttributes { id: string; some_required_property: number; some_optional_property?: number; } // 定义创建模型时需要传入的属性:排除自动生成的id,保留必填项 interface MyModelCreationAttributes extends Omit<MyModelAttributes, 'id'> {} // 扩展Model时传入明确的属性类型 interface MyModelSchema extends Model<MyModelAttributes, MyModelCreationAttributes> { id: CreationOptional<string>; } type MyModel = ModelStatic<MyModelSchema>; declare const MyModel: MyModel;
方案2:修正现有接口的推断逻辑
若想保留原有接口结构,可通过显式约束创建属性的类型来强制必填项:
import { Model, ModelStatic, CreationOptional, InferAttributes, InferCreationAttributes } from 'sequelize'; interface MyModelSchema extends Model<InferAttributes<MyModelSchema>, InferCreationAttributes<MyModelSchema>> { id: CreationOptional<string>; some_required_property: number; some_optional_property?: number; } // 显式指定创建属性中some_required_property为必填 type MyModelCreationAttrs = Omit<InferCreationAttributes<MyModelSchema>, 'id'> & Required<Pick<InferCreationAttributes<MyModelSchema>, 'some_required_property'>>; // 重新定义Model类型,绑定修正后的创建属性 type MyModel = ModelStatic<MyModelSchema, MyModelCreationAttrs>; declare const MyModel: MyModel;
效果验证
修改后,调用MyModel.create()时TypeScript会强制要求传入some_required_property,而id和some_optional_property保持可选:
const document = MyModel.create({ some_required_property: 123 // 必填项,未传入会触发类型错误 // some_optional_property: 456 // 可选,可按需传入 });
内容的提问来源于stack exchange,提问作者asportnoy
相关产品推荐
相关产品推荐

