TypeScript子类调用父类方法返回类型错误问题排查与优化
父类方法返回正确子类模型结果的解决方案
问题描述
父类实现通用方法,子类继承后指定具体模型,但调用父类方法时,返回结果始终是基类BaseModel的方法结果,而非子类指定的MyModel结果。代码示例:
class Parent<M extends typeof BaseModel> { model: M getList(){ return this.model.queryList() } } class Child extends Parent<typeof MyModel>{ model: typeof MyModel constructor(){ super(); this.model = MyModel; } } const childProvider = new Child(); childProvider.getList() // 实际返回BaseModel.queryList()结果,而非预期的MyModel.queryList()结果
需求:无需重写父类所有方法,让父类方法调用时返回对应子类模型的正确结果。
解决方案
方案1:构造函数注入模型类型
修改父类,通过构造函数接收模型类型参数,子类在实例化时传入指定模型。这种方式能让TypeScript准确推断泛型类型,确保父类方法关联正确的模型:
class Parent<M extends typeof BaseModel> { constructor(public model: M) {} getList() { return this.model.queryList() } } class Child extends Parent<typeof MyModel> { constructor() { super(MyModel); } } const childProvider = new Child(); childProvider.getList() // 正确返回MyModel.queryList()的结果
方案2:移除子类中重复的model属性声明
子类重复声明model: typeof MyModel会覆盖父类的泛型类型绑定,导致父类方法无法识别子类的模型类型。移除该声明后,子类的model会继承父类的泛型约束M(即typeof MyModel):
class Parent<M extends typeof BaseModel> { model: M getList(){ return this.model.queryList() } } class Child extends Parent<typeof MyModel>{ constructor(){ super(); this.model = MyModel; } } const childProvider = new Child(); childProvider.getList() // 正确返回MyModel.queryList()的结果
原因解析
- 方案1通过构造函数注入模型,让父类在初始化阶段就绑定了子类指定的模型类型,从根源上避免了类型推断偏差。
- 方案2中,子类重复声明
model属性会破坏泛型继承的类型关联,父类方法会默认使用基类BaseModel的类型;移除重复声明后,父类泛型M会正确关联到子类指定的MyModel类型,方法调用自然返回正确结果。
内容的提问来源于stack exchange,提问作者Horhi
相关产品推荐
相关产品推荐

