【发布时间】:2019-01-01 16:32:59
【问题描述】:
class Foo {
foo: () => void
}
class Bar extends Foo {
foo() {}
}
有没有办法告诉 TypeScript 允许上面的例子?
类 'Foo' 定义了实例成员属性 'foo',而扩展类 'Bar' 将其定义为实例成员函数。
【问题讨论】:
标签: typescript
class Foo {
foo: () => void
}
class Bar extends Foo {
foo() {}
}
有没有办法告诉 TypeScript 允许上面的例子?
类 'Foo' 定义了实例成员属性 'foo',而扩展类 'Bar' 将其定义为实例成员函数。
【问题讨论】:
标签: typescript
那是因为您可以调用父方法,但不能调用父实例成员。
原因是正确的方法被保存到原型链中,而成员函数没有。
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)是安全的,但反之则不然。
【讨论】:
TypeScript 允许反过来。 ??
class Foo {
foo() { }
}
class Bar extends Foo {
foo: () => void
constructor() {
super()
this.foo = () => { }
}
}
您也可以在方法前加上下划线,然后在构造函数中绑定它。 ??
class Foo {
foo: () => void
}
class Bar extends Foo {
constructor() {
super()
this.foo = this._foo.bind(this)
}
_foo() {}
}
如果 TypeScript 允许您执行以下操作,那就太好了:
class Foo {
foo: () => void
}
class Bar extends Foo {
constructor() {
super()
// TypeScript should see that the method is always bound.
this.foo = this.foo.bind(this)
}
foo() {}
}
【讨论】: