打字稿:从扩展 class 调用超级方法给出类型错误 - (中间值)不是函数
Typescript: calling super method from extended class gives type error - (intermediate value) is not a function
我正在一个名为 StructureWindowComponent 的组件中实现事件处理,并且还在 LeggerStructureWindowComponent 中对其进行了覆盖..
基础class(StructureWindowComponent)中blur事件的事件处理如下:
symbolCellLostFocus = (symbolField : MatInput, $index: number) =>{
console.log("base class symbol cell lost focus");
//implementation...
}
在派生的 class LeggerStructureWindowComponent 中,我像这样使用 super 调用此方法...
symbolCellLostFocus = (symbolField : MatInput, $index: number) =>{
console.log("derived class symbol lost focus");
super.symbolCellLostFocus(symbolField, $index);
}
我在控制台中收到错误消息:
错误类型错误:(中间值).symbolCellLostFocus 不是函数
不确定这里有什么问题..有人可以指点一下吗?
这是一个棘手的问题,但它与 类 中箭头函数语法的使用以及原型链有关。具体与Angular无关。
基本上,如果您想解决问题,您需要将 a = () => { ... }
替换为 a() { ... }
:
symbolCellLostFocus(symbolField : MatInput, $index: number) {
console.log("base class symbol cell lost focus");
//implementation...
}
symbolCellLostFocus(symbolField : MatInput, $index: number) {
console.log("derived class symbol lost focus");
super.symbolCellLostFocus(symbolField, $index);
}
现在进行解释,如果您编写以下代码段:
class A {
name = 'A'
sayHello = () => {
console.log('Hello from A')
}
}
class B extends A {
name = 'B'
sayHello = () => {
console.log('Hello from B')
super.sayHello()
}
}
它被转换成这个JavaScript片段:
class A {
constructor() {
this.name = 'A';
this.sayHello = () => {
console.log('Hello from A');
};
}
}
class B extends A {
constructor() {
super(...arguments);
this.name = 'B';
this.sayHello = () => {
console.log('Hello from B');
super.sayHello();
};
}
}
如您所见,方法是在构造函数中定义的,每个实例 由构造函数创建。这意味着 A
中的方法 sayHello
不适用于 B
,因为 sayHello
在 B
的原型中不可用(即 A
),它仅适用于 A
的每个实例。这可能会造成混淆,我强烈建议在 JavaScript!
中学习原型继承
类在ES2015中引入,只是JavaScript中原型继承的语法糖。 class
、constructor
、super
等关键字只是抽象出编写原型链所需的语法。本质上就是JavaScript中实现组合和继承的方式,非常强大的概念。
无论如何,当您在这里写 super.X()
时,JavaScript 引擎正在尝试访问原型上的 X
方法,该方法不存在。你最终得到 Object.getPrototypeOf(this).undefined()
,而 undefined
确实不是一个函数,所以你得到一个 TypeError: (intermediate value).sayHello is not a function
运行时错误。
这里有一个例子来说明我所说的:TS playground.
我正在一个名为 StructureWindowComponent 的组件中实现事件处理,并且还在 LeggerStructureWindowComponent 中对其进行了覆盖..
基础class(StructureWindowComponent)中blur事件的事件处理如下:
symbolCellLostFocus = (symbolField : MatInput, $index: number) =>{
console.log("base class symbol cell lost focus");
//implementation...
}
在派生的 class LeggerStructureWindowComponent 中,我像这样使用 super 调用此方法...
symbolCellLostFocus = (symbolField : MatInput, $index: number) =>{
console.log("derived class symbol lost focus");
super.symbolCellLostFocus(symbolField, $index);
}
我在控制台中收到错误消息: 错误类型错误:(中间值).symbolCellLostFocus 不是函数
不确定这里有什么问题..有人可以指点一下吗?
这是一个棘手的问题,但它与 类 中箭头函数语法的使用以及原型链有关。具体与Angular无关。
基本上,如果您想解决问题,您需要将 a = () => { ... }
替换为 a() { ... }
:
symbolCellLostFocus(symbolField : MatInput, $index: number) {
console.log("base class symbol cell lost focus");
//implementation...
}
symbolCellLostFocus(symbolField : MatInput, $index: number) {
console.log("derived class symbol lost focus");
super.symbolCellLostFocus(symbolField, $index);
}
现在进行解释,如果您编写以下代码段:
class A {
name = 'A'
sayHello = () => {
console.log('Hello from A')
}
}
class B extends A {
name = 'B'
sayHello = () => {
console.log('Hello from B')
super.sayHello()
}
}
它被转换成这个JavaScript片段:
class A {
constructor() {
this.name = 'A';
this.sayHello = () => {
console.log('Hello from A');
};
}
}
class B extends A {
constructor() {
super(...arguments);
this.name = 'B';
this.sayHello = () => {
console.log('Hello from B');
super.sayHello();
};
}
}
如您所见,方法是在构造函数中定义的,每个实例 由构造函数创建。这意味着 A
中的方法 sayHello
不适用于 B
,因为 sayHello
在 B
的原型中不可用(即 A
),它仅适用于 A
的每个实例。这可能会造成混淆,我强烈建议在 JavaScript!
类在ES2015中引入,只是JavaScript中原型继承的语法糖。 class
、constructor
、super
等关键字只是抽象出编写原型链所需的语法。本质上就是JavaScript中实现组合和继承的方式,非常强大的概念。
无论如何,当您在这里写 super.X()
时,JavaScript 引擎正在尝试访问原型上的 X
方法,该方法不存在。你最终得到 Object.getPrototypeOf(this).undefined()
,而 undefined
确实不是一个函数,所以你得到一个 TypeError: (intermediate value).sayHello is not a function
运行时错误。
这里有一个例子来说明我所说的:TS playground.