TypeScript TS2345错误:子类函数无法赋值给父类类型参数
问题原因与解决方案
问题代码
class Cache { constructor(f: (o: CachableDBObject) => CachableDBObject) { } } abstract class CachableDBObject { } class Car extends CachableDBObject { static create = new Cache((o: Car) => { return o; }) s: string; }
报错原因
TypeScript 对函数类型的兼容性遵循逆变-协变规则:
- 返回值类型是协变的:返回子类型可以兼容父类型的要求(比如返回
Car满足返回CachableDBObject的要求) - 参数类型是逆变的:要求接受父类型参数的函数,不能传入只接受子类型参数的函数
Cache构造函数要求的函数能接受任意CachableDBObject子类实例,但你传入的函数只接受Car类型。假设后续有另一个Truck extends CachableDBObject,Cache可能会把Truck实例传给这个函数,而函数期望的Car有s属性,Truck没有,这就会导致运行时错误。TypeScript提前拦截了这个潜在风险,所以抛出了类型不兼容的错误。
解决方案
把Cache改成泛型类,让它和具体的子类类型绑定,这样就能保证函数的参数和返回值类型匹配:
class Cache<T extends CachableDBObject> { constructor(f: (o: T) => T) { } } abstract class CachableDBObject { } class Car extends CachableDBObject { static create = new Cache<Car>((o: Car) => { return o; }) s: string; }
这样Cache的构造函数参数就会约束为接受T类型(这里是Car)并返回T类型的函数,完全符合你传入的函数类型,不会再触发类型错误。
内容的提问来源于stack exchange,提问作者andreash
相关产品推荐
相关产品推荐

