如何阻止TypeScript允许父类替代子类传入?
问题解答
为什么代码能正常运行?
TypeScript采用结构类型系统,类型兼容性判断的核心是「结构是否匹配」,而非类的继承关系。
在你的代码中:
Child继承自Parent,但没有新增任何公共属性或方法;Parent的bar方法返回string(foo是字符串类型),Child的bar同样返回string;- 从结构上看,
Parent实例拥有Child类型要求的所有成员,因此TypeScript判定Parent类型兼容Child类型,允许传入父类实例。
如何限制并触发类型错误?
要让TypeScript区分继承关系中的父类和子类,需要给类添加唯一的结构标记,破坏两者的结构兼容性。常见的实现方式有两种:
方式1:添加私有属性
给父类和子类分别添加私有属性,利用私有属性仅对当前类可见的特性,让两者结构不再兼容:
class Parent { constructor(private foo: string) {} // 父类专属私有标记 private readonly _parentBrand = true; bar() { return this.foo; } } class Child extends Parent { // 子类专属私有标记 private readonly _childBrand = true; bar() { return 'baz'; } } function doSomething(item: Child) {} doSomething(new Parent('')); // 触发类型错误:类型 "Parent" 的参数不能赋给类型 "Child" 的参数
方式2:使用符号(Symbol)标记
通过唯一的Symbol属性作为类型标记,同样能破坏结构兼容性:
const parentSymbol = Symbol(); const childSymbol = Symbol(); class Parent { constructor(private foo: string) {} [parentSymbol] = true; bar() { return this.foo; } } class Child extends Parent { [childSymbol] = true; bar() { return 'baz'; } } function doSomething(item: Child) {} doSomething(new Parent('')); // 触发类型错误
内容的提问来源于stack exchange,提问作者lolgab123
相关产品推荐
相关产品推荐

