Typescript 子类不能使用subtype属性代替父类属性
好吧,奇怪的标题,不知道该怎么说。 这就是问题所在。 我的印象是,如果我将父构造函数属性的子类型传递给子构造函数属性,那么一切都将正常工作。然而,情况并非如此。如果我试图在子属性上使用subtype方法,我会得到一个错误Typescript 子类不能使用subtype属性代替父类属性,typescript,Typescript,好吧,奇怪的标题,不知道该怎么说。 这就是问题所在。 我的印象是,如果我将父构造函数属性的子类型传递给子构造函数属性,那么一切都将正常工作。然而,情况并非如此。如果我试图在子属性上使用subtype方法,我会得到一个错误 接口IDataPaper{ save():void } 接口IReactiveDataMapper扩展了IDataPaper{ saveReactive():void } 甲级{ 构造函数(受保护的映射器:IDataMaper){} } B类扩展了A类{ 构造函数(映射器:IR
接口IDataPaper{
save():void
}
接口IReactiveDataMapper扩展了IDataPaper{
saveReactive():void
}
甲级{
构造函数(受保护的映射器:IDataMaper){}
}
B类扩展了A类{
构造函数(映射器:IReactiveDataMapper){
超级(映射器)//这里没有错误
//this.mapper.saveReactive()//错误
}
}
问题在于,您正在从
此
上下文访问映射器
实例。请注意类A的构造函数中的protected mapper:IDataMapper
。通过在此处预加关键字protected
,可以强制类A将有一个名为mapper
的受保护成员,其类型为IDataMapper
。在B的构造函数中,您没有关键字protected
,这意味着B的此-上下文的受保护成员mapper
不会被覆盖,并且使用A存储的IDataMapper
-属性。向B的构造函数中的变量添加一个受保护的-前缀,使其覆盖成员,您将不会遇到错误
interface IDataMaper{
save():void
}
interface IReactiveDataMapper extends IDataMaper{
saveReactive():void
}
class A {
constructor(protected mapper: IDataMaper) {}
}
class B extends A {
constructor(protected mapper: IReactiveDataMapper) {
super(mapper);
this.mapper.saveReactive();
}
}
卢卡斯的回答很好地解释了为什么会出现这种错误;this.mapper
的类型是IDataMapper
,而不是更具体的类型IReactiveDataMapper
作为不需要更改字段类型或使用其他类型声明新字段的替代解决方案,您可以在参数mapper
上调用该方法,该参数引用与this.mapper相同的对象,但具有更具体的类型:
B类扩展了A类{
构造函数(映射器:IReactiveDataMapper){
超级(制图员);
mapper.saveReactive();//而不是this.mapper
}
}
如果只需要构造函数中更具体的类型,则此选项可能更简单,如示例中所示。如果您需要this.mapper
在子类中的其他方法中具有更具体的类型,那么Lukas的答案是最好的方法。事实上,我一开始就是这样做的,但是如果您查看“B”类构造函数生成的代码,“mapper”属性将立即重新分配,这将完全覆盖父类中的属性以及该属性的任何初始化。是的,但在B的构造函数中,您正在访问this.mapper
属性,因此您有两个选项作为答案,覆盖子类B中的this.mapper
,或者按照@kaya3的建议,不要直接访问this.mapper
,而是直接访问mapper
。否则我不确定你想要实现什么。我不明白为什么演示中的代码会显示错误。由于mapper
是一个子类型,因此它保证拥有父类型所拥有的一切。如前所述,我需要在类的其他方法中访问mapper
,因此我需要this.mapper
我还需要从类的其他方法中访问“mapper”属性。