我在Angular 5中有一个带有抽象类和接口的长继承链。它抛出了一个错误error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword.
抽象父类的方法定义为:
public get text() {
return this.el.attr('text/text').replace("\n", "");
}
子类的方法定义为:
public get text(): string {
return super.text;
}
如何让子类不抛出TS2340错误?
我创建了一个用于演示问题的stackblitz:
https://stackblitz.com/edit/ts2340-super-keywork-public?file=app%2Fnodes.ts
不幸的是,TS并不支持这一点,它的外观永远不会是:
https://github.com/Microsoft/TypeScript/issues/338
看起来目前唯一可行的方法就是在你的compiler options中攻击ES6
正如另一个答案所解释的那样,TypeScript中的转换类的设计不支持这一点。
一个可能的解决方案是desugar super.property
,即从父类原型中的描述符获取getter函数并将其应用于类实例。这可以通过Reflect.get
实现:
class Foo {
get foo() {
return 'foo';
}
}
class Bar extends Foo {
get foo() {
return <Foo['foo']>Reflect.get(Foo.prototype, 'foo', this) + 'bar';
}
}
new Bar().foo === 'foobar';
这是一个糟糕的错误消息,但非常重要的是不要忽略它!
导致我出现此错误的代码如下:
private _name: string;
public get name(): string { return this._name; }
public set name(name: string) { this._name = name; }
super.name = "Simon"; // seems innocuous enough right?
然后我得到了错误:
错误TS2340:只能通过'super'关键字访问基类的公共和受保护方法。
当你做super.name
时,实际上你在超类上覆盖了实现本身。所以我只成功将name
转换为全局静态属性。然后我会访问name
的任何地方,我会得到我设置的最后一个值。
super
to this
:this.name = "Simon";
所以不要忽略这个编译错误!