简体   繁体   English

打字稿:从扩展类调用超级方法会产生类型错误 - (中间值)不是函数

[英]Typescript: calling super method from extended class gives type error - (intermediate value) is not a function

I am implementing event handling in a component named StructureWindowComponent and also have an override for it in LeggerStructureWindowComponent..我正在一个名为 StructureWindowComponent 的组件中实现事件处理,并且在 LeggerStructureWindowComponent 中也有一个覆盖它。

In the base class (StructureWindowComponent) the event handling for blur event is as follows:在基类(StructureWindowComponent)中,模糊事件的处理如下:

 symbolCellLostFocus = (symbolField : MatInput, $index: number) =>{ console.log("base class symbol cell lost focus"); //implementation... }

In the derived class LeggerStructureWindowComponent, I am calling this method using super like this...在派生类 LeggerStructureWindowComponent 中,我像这样使用 super 调用此方法...

symbolCellLostFocus = (symbolField : MatInput, $index: number) =>{
    console.log("derived class symbol lost focus");
    super.symbolCellLostFocus(symbolField, $index);
  }

I get the error in the console: ERROR TypeError: (intermediate value).symbolCellLostFocus is not a function我在控制台中收到错误消息:ERROR TypeError: (intermediate value).symbolCellLostFocus is not a function

Not sure what is wrong here.. can someone please advice?不知道这里出了什么问题..有人可以请教吗?

This is a tricky one, but it has to do with the use of arrow functions syntax in classes, and the prototype chain.这是一个棘手的问题,但它与类中箭头函数语法的使用以及原型链有关。 It is not related to Angular specifically.它与 Angular 没有特别的关系。

Basically if you want to fix your issue, you need to replace a = () => { ... } with a() { ... } :基本上,如果你想解决你的问题,你需要用a() { ... }替换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);
}

Now for the explanation, if you write the following snippet:现在解释一下,如果您编写以下代码段:

class A {
    name = 'A'
    sayHello = () => {
        console.log('Hello from A')
    }
}

class B extends A {
    name = 'B'
    sayHello = () => {
        console.log('Hello from B')
        super.sayHello()
    }
}

It is transformed into this JavaScript snippet:它被转换成这个 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();
        };
    }
}

As you can see, the methods are defined in the constructor, for each instance created by the constructors.如您所见,方法是在构造函数中为每个由构造函数创建的实例定义的。 This means that the method sayHello from A is not available for B , because sayHello is not available in the prototype of B (which is A ), it is only available for each instance of A .这意味着来自A的方法sayHello不可用于B ,因为sayHelloB的原型(即A )中不可用,它仅可用于A每个实例。 This can be confusing, I highly recommend learning about prototype inheritance in JavaScript!这可能会令人困惑,我强烈建议您学习 JavaScript 中的原型继承!

Classes, introduced in ES2015, are just syntactic sugar for prototype inheritance in JavaScript. ES2015 中引入的类只是 JavaScript 中原型继承的语法糖。 The class , constructor , super , etc. keywords only abstract the syntax needed to write prototype chains. classconstructorsuper等关键字仅抽象了编写原型链所需的语法。 Essentially, it's the way to achieve composition and inheritance in JavaScript, a very powerful concept.本质上,它是在 JavaScript 中实现组合和继承的方式,这是一个非常强大的概念。

Anyway, when you write super.X() here, the JavaScript engine is trying to access the X method on the prototype, which doesn't exist.无论如何,当您在这里编写super.X() ,JavaScript 引擎正在尝试访问原型上不存在的X方法。 You end up with Object.getPrototypeOf(this).undefined() , and undefined is indeed not a function, so you get a TypeError: (intermediate value).sayHello is not a function runtime error.你最终得到Object.getPrototypeOf(this).undefined() ,而undefined确实不是一个函数,所以你得到一个TypeError: (intermediate value).sayHello is not a function运行时错误。

Here's an example to illustrate what I said: TS playground .这里有一个例子来说明我所说的: TS playground

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Typescript: (中间值).(…) 不是 function 当从派生的 class 调用父 class 的方法时 - Typescript: (intermediate value).(…) is not a function when call a method of parent class from derived class 从扩展 Electron class 调用 class 方法时出错 - Error calling class method from extended Electron class 在扩展类中从异步方法调用超类'异步方法 - Calling super class' async method from async method in extending class Javascript,从覆盖方法调用超类方法的便捷方法 - Javascript, convenience method for calling super class method from overwritten method Typescript 不允许扩展的 class promise 成为异步 ZC1C425268E68385D1AB4Z5074C 的返回类型 - Typescript does not allow an extended class promise to be the return type of an async function 在Backbone中调用超类方法 - Calling super class method in Backbone 从类方法中调用函数 - Calling a function from a class method 流类型:使用来自返回父类的函数的扩展类 - Flow type: use extended class from function returning parent class JS(中间值).g 不是 function 中间值不是 function 使用超级运算符时 - JS (intermediate value).g is not a function intermediate value is not a function when using super operator TypeScript 从扩展类型创建省略类型 - TypeScript create Omit type from extended type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM