TypeScript: Return value of super() calls not used for `this`
If a constructor returns a value other than this, then in subclasses super() calls to that constructor should use the result as this in the subclass constructor.
I believe this is specified in 12.3.5.1, step 10 of SuperCall: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-super-keyword
Getting this behavior correct is going to be very important for supporting Custom Elements, which takes advantage of this to initialize browser-allocated elements with user-written constructors. See https://w3c.github.io/webcomponents/spec/custom/#htmlelement-constructor
Note, Babel 6 implements this correctly.
TypeScript Version:
1.8.9
Code
class Foo {
x : number;
constructor() {
return {
x: 1,
};
}
}
class Bar extends Foo {
y : number;
constructor() {
super();
this.y = 2;
}
}
let o = new Bar();
console.assert(o.x === 1 && o.y === 2);
Expected behavior:
No assertion error
The constructor for Bar should compile to this:
var Bar = (function (_super) {
__extends(Bar, _super);
function Bar() {
var _this = _super.call(this);
_this.x = 1;
return _this;
}
return Bar;
}(Foo));
Actual behavior:
Assertion error
The constructor for Bar compiles to this:
var Bar = (function (_super) {
__extends(Bar, _super);
function Bar() {
_super.call(this);
this.x = 1;
}
return Bar;
}(Foo));
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 17 (7 by maintainers)
@jeffmcaffer This isn’t necessarily true,
new Bar()can return aBareven if it’s not returningthis. It can easily type check - this has nothing to do with types. The return type ofsuper()should be the return type ofnewin the super constructors interface.For instance, this should fully type check:
@mhegazy I’d like to point out that Typescript is in direct violation of the ECMAScript spec, and because of this you won’t be able to write Custom Elements in Typescript compiled to ES5*. I hope that if this behavior is “By Design” that the design can still be changed so that Typescript correctly implements ES2016 and is actually a superset rather a separate language.
*Targeting ES2015 should probably work, because ES2015 just works this way.