好吧,奇怪的标题,不知道该怎么说。 所以这就是问题所在。 我的印象是,如果我将父构造函数属性的子类型传递给子构造函数属性,一切都会起作用。然而,事实并非如此。如果我尝试在子属性上使用子类型方法,则会出现错误。
interface IDataMaper{
save():void
}
interface IReactiveDataMapper extends IDataMaper{
saveReactive():void
}
class A {
constructor(protected mapper: IDataMaper) {}
}
class B extends A {
constructor(mapper: IReactiveDataMapper) {
super(mapper)//no errror here
// this.mapper.saveReactive() //error
}
}
打字稿游乐场
问题是您正在从this
上下文访问mapper
实例。请注意类 A 的构造函数中的protected mapper: IDataMapper
。通过将关键字protected
添加到前面,可以强制类 A 将具有一个名为mapper
的受保护成员,其类型为IDataMapper
。在 B 的构造函数中,您没有关键字protected
,这意味着 B 的this
-context 的受保护成员mapper
不会被覆盖,并且使用 A 存储的IDataMapper
属性。将protected
-前缀添加到 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();
}
}
游乐场链接
Lukas的回答很好地解释了为什么会发生这个错误;this.mapper
的类型是IDataMapper
,而不是更具体的IReactiveDataMapper
类型。
作为不需要更改字段类型或使用不同类型的新字段声明的替代解决方案,您可以在参数mapper
上调用该方法,该方法引用与this.mapper
相同的对象,但具有更具体的类型:
class B extends A {
constructor(mapper: IReactiveDataMapper) {
super(mapper);
mapper.saveReactive(); // instead of this.mapper
}
}
如果只需要构造函数中更具体的类型,则此选项可能更简单,如示例中所示。如果你需要this.mapper
在子类中的其他方法中拥有更具体的类型,那么 Lukas 的答案是最好的方法。