在覆盖派生类中的静态字段时,"...错误地扩展了基类静态端"错误

dod*_*951 5 inheritance static-variables typescript

覆盖派生类中的静态字段会导致

错误TS2417:构建:类静态端'typeof TDerived'错误地扩展了基类静态端'typeof TBase'.

这是一个合法的错误案例吗?

class TBase
{
  private static s_field = 'something';

  public constructor() {}
}

class TDerived extends TBase
{
  private static s_field = 'something else'; // commenting this line fixes error

  public constructor()
  {
    super();
  }
}
Run Code Online (Sandbox Code Playgroud)

那我该怎么处理静态字段呢?现在唯一的解决方法是将类名添加到每个静态字段名称,这是一个非常难看的解决方案.

private static TBase_s_field = 'something';
...
private static TDerived_s_field = 'something else';
Run Code Online (Sandbox Code Playgroud)

ps使用typescript 2.0.3

Rya*_*ugh 2

您不能private在派生类中重新声明字段。protected如果您希望派生类能够重新声明或访问该字段,请使用该字段。

这是强制执行的,因为静态方法在派生类中也可用。例如,这段代码做了一些意想不到的事情(如果我们忽略编译错误):

class Base {
    private static foo = 'base';

    static printName() {
        // Should always print 'base' because no one
        // else has access to change 'foo'
        console.log(this.foo);
    }
}

class Derived extends Base {
    private static foo = 'derived';
}
// Will actually print 'derived'
Derived.printName();
Run Code Online (Sandbox Code Playgroud)

  • 不,不会的。Javascript 使用基于原型的继承,因此派生类静态端中的静态字段将始终正确覆盖基类静态端中的静态字段(通过直接访问基类静态端仍然可用)。当 Javascript 解释器发现 TDerived 有 s_field 时,它不会更深入地检查 TDerived.prototype 中是否存在 s_field。private modded 的唯一区别(至少假设是这样)是强制 typescript 编译器禁止在类代码之外访问 s_field (在编译时)。 (4认同)