如何修改DatabaseObjectModel<T>构造器使其接受T类型普通对象而非实例
问题根因
你遇到的报错是因为子类ImplementingDatabaseObjectModel继承DatabaseObjectModel时,错误地将泛型参数T指定为了子类本身的类型,导致构造函数入参被限制为必须是子类实例,而非符合属性要求的普通对象。
修复方案
步骤1:调整父类类型定义
先修正JSONModel和DatabaseObjectModel的泛型关联,确保入参类型和泛型对齐:
export default abstract class JSONModel<T> extends ModelValidation { toJSON() { // Default toJSON return JSON.parse(JSON.stringify(this)); } // 将fromJSON入参从Object改为泛型T fromJSON(json: T) { // For each key of json, assign value to this.key for (let key in json) { // 可加索引签名或@ts-ignore避免类型赋值报错 (this as Record<string, any>)[key] = json[key]; } } } export default abstract class DatabaseObjectModel<T> extends JSONModel<T> { // 构造函数入参保持T即可,不需要额外修改类型 constructor(json: T) { super(); this.fromJSON(json); } }
步骤2:定义属性接口、正确继承父类
先将你需要的业务属性抽为独立接口,子类继承父类时将该接口作为泛型传入,不要传入子类自身类型:
// 抽离业务属性接口 interface IBusinessProps { id: string; name: string; permissions: unknown[]; assignedRoles?: unknown[]; // 可选属性兼容undefined赋值 } // 子类继承时泛型传属性接口,而非子类自身 class ImplementingDatabaseObjectModel extends DatabaseObjectModel<IBusinessProps> { // 子类声明对应属性,匹配接口定义 id: string; name: string; permissions: unknown[]; assignedRoles?: unknown[]; }
步骤3:验证初始化调用
此时再执行初始化操作就不会出现类型报错:
new ImplementingDatabaseObjectModel({ id: randomUUID(), name: "MASTER", permissions: [], assignedRoles: undefined, })
可选优化
如果不想在子类重复声明接口中的属性,可以给父类添加索引签名[key: string]: any,可以省去重复的属性声明,缺点是会丢失部分类型校验能力。
内容的提问来源于stack exchange,提问作者Constantin
相关产品推荐
相关产品推荐

