TypeScript错误 - TS2340:通过'super'关键字可访问公共方法

10

我的Angular 5项目中有一个继承链很长的抽象类和接口。它抛出了一个错误:error TS2340:仅通过“super”关键字可以访问基类的公共和受保护方法。

抽象父类定义了该方法:

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


1
不要简单地将get texts()函数放在您的子类中。如果一个类继承自另一个类,那么子类就拥有了父类的所有函数(方法)。 - Eliseo
2
@Eliseo 这对于这段代码是正确的。如果子获取器不同可能不是这样。 - Estus Flask
3个回答

14

这是一个糟糕的错误信息,但非常重要不要忽略它!

导致我遇到此错误的代码如下:

Tracker.ts

private _name: string;
public get name(): string { return this._name; }
public set name(name: string) { this._name = name; }

SubTracker.ts(扩展Tracker)

super.name = "Simon";   // seems innocuous enough right? 

然后我遇到了错误:

error TS2340:只有基类的公共和受保护方法可以通过“super”关键字访问。

事实证明,当你使用super.name时,你实际上是覆盖了超类自身的实现。因此,我只成功地将name转换为全局静态属性。然后无论何处我访问name,我都会得到我设置的最后一个值。


那么如何修复?将super更改为this

this.name = "Simon";

所以不要忽视这个编译错误!


1
如果您实际上正在覆盖getter(如OP的问题中所示),那么仅使用this.是行不通的,因为this.name将指向自身。您可以使用普通函数代替getter,或将编译目标更改为ES6(请参见@klugjo的答案)。 - Arno van Oordt

8

3
这就是答案,大多数人无论如何都不需要针对es5进行目标定位。 - chrismarx

3

正如另一个答案所解释的那样,TypeScript中转换后的类不支持此功能。

一种可能的解决方案是对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';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接