Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 子类不能使用subtype属性代替父类属性_Typescript - Fatal编程技术网

Typescript 子类不能使用subtype属性代替父类属性

Typescript 子类不能使用subtype属性代替父类属性,typescript,Typescript,好吧,奇怪的标题,不知道该怎么说。 这就是问题所在。 我的印象是,如果我将父构造函数属性的子类型传递给子构造函数属性,那么一切都将正常工作。然而,情况并非如此。如果我试图在子属性上使用subtype方法,我会得到一个错误 接口IDataPaper{ save():void } 接口IReactiveDataMapper扩展了IDataPaper{ saveReactive():void } 甲级{ 构造函数(受保护的映射器:IDataMaper){} } B类扩展了A类{ 构造函数(映射器:IR

好吧,奇怪的标题,不知道该怎么说。 这就是问题所在。 我的印象是,如果我将父构造函数属性的子类型传递给子构造函数属性,那么一切都将正常工作。然而,情况并非如此。如果我试图在子属性上使用subtype方法,我会得到一个错误

接口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”属性。