'How to call a method of a derived class in the constructor of this derived class
I have a piece of code that used to work in TypeScript a few years ago, but now is begin compiled using Microsoft.TypeScript.MSBuild 4.5.3 (as part of a Microsoft.NET.Sdk.Web NET 5.0 project) and no longer works. Previously code must have been compiled using an older version of this compiler, but I can't pinpoint which version (it was a TypeScript project in Visual studio 2017 or older). Here is a stripped down version of my code:
class MyArray extends Array<number>{
constructor(x: number)
{
super();
this.foo(x);
}
foo(x: number) {
// Do stuff with x
}
}
Creating a new instance of MyArray results in the exception: Uncaught TypeError: _this.foo is not a function
It appears to boil down to the constructor being compiled to:
var _this = _super.call(this) || this;
_this.foo(x)
If I understand it correctly, _this is an instance of an Array<number> and knows nothing of my foo method.
In the past the constructor would compile to:
_super.call(this);
this.foo(x)
which would work.
I desperately tried to find an answer to this problem on the internet, but had no luck. Adding to the confusion, intelisense and the compiler don't expect there to be a problem (probably because this code would work in a non-inherited class) and the debugger in the browser still firmly believes that this in my TypeScript constructor is an instance of MyArray rather than Array<number>.
Long story short, how can I call my foo method from the constructor of MyArray class?
Solution 1:[1]
Thanks to tips form Nalin Ranjan, I was able to figure out how to solve my problem. After switching my project to Microsoft.NET.Sdk.Web NET 5.0 I made no adjustments to the TypeScript compiler configuration. For some reason that meant my target was ES5 (I mistakenly expected it to default to a newer version of TypeScript and ES5 to somehow be a newer target). After changing the target to ES2017 (which I probably had in the old version of my project), everything started working as expected.
Solution 2:[2]
To be able to have a foo being called the way we want to with ES5 target, try this...
class MyArray extends Array<number> {
constructor(x: number) {
super();
this.foo(x);
}
// A property foo as arrow function, instead of a member function on the class
foo = (x: number) => {
// Do stuff with x
console.log('foo called with', x);
}
}
let c = new MyArray(6);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | jahu |
| Solution 2 |
