允许子类使用函数属性或方法覆盖

时间:2019-01-01 16:33:00

标签: typescript

class Foo {
  foo: () => void
}

class Bar extends Foo {
  foo() {}
}

有什么办法告诉TypeScript允许上面的示例?

Playground

  

'Foo'类定义实例成员属性'foo',但扩展类'Bar'将其定义为实例成员函数。

2 个答案:

答案 0 :(得分:2)

那是因为您可以调用父方法,但不能调用父实例成员。

之所以这样做是因为正确的方法保存在原型链中,而成员函数却没有。

class Foo {
    foo() {
        return `Successfully called Foo.foo()`;
    }

    bar = () => {
        return `Successfully called Foo.bar()`;
    }
}

console.log(
    ('foo' in Foo.prototype), // true (methods are correctly inherited)
    ('bar' in Foo.prototype), // false (instance properties are not inherited)
);

如果该属性不在属性链中,则尝试使用super进行调用将导致运行时错误。

class Bar extends Foo {
    foo = () => {
        return super.foo(); // Good: `foo` is in the prototype chain
    }

    bar = () => {
        return super.bar(); // Runtime error: `bar` is not in the prototype chain
    }
}

这样可以安全地从方法转到类实例属性(在这里为foo),但不能相反。

答案 1 :(得分:0)

TypeScript允许使用另一种方法。

for SomeType

您还可以在方法前加上下划线,然后将其绑定到构造函数中。

class Foo {
  foo() { }
}

class Bar extends Foo {
  foo: () => void
  constructor() {
    super()
    this.foo = () => { }
  }
}

如果TypeScript允许您执行以下操作,那就太好了

class Foo {
  foo: () => void
}

class Bar extends Foo {
  constructor() {
    super()
    this.foo = this._foo.bind(this)
  }
  _foo() {}
}