Repository navigation
Bug or breaking change in super constructors? #12669
Description
Activity
- addedBugA bug in TypeScriptA bug in TypeScript
on Dec 5, 2016 I'll take a look, though this may be an error at runtime in native ES6.
This should be an error. the emit is rather secondary (though we should fix it).
also this should be an error, though it emits correctly:
class Dog extends Animal { constructor() { var x = super.GetName(); // implicit use of `this` before it is defined } }
Reacted by Elephant-Vessel and Andrew RossWould you still be able to allow calls to super directly after the super-constructor is called, even if inside the derived constructor? The absence of any call to super in your above example made me unsure about your intentions.
class Dog extends Animal { constructor() { super("foo"); var superName = super.GetName(); // Ok? } }
Would you still be able to allow calls to super directly after the super-constructor is called, even if inside the derived constructor?
This is valid code, and should work now anyways.
the issue is the order.
thisis not defined untilsuper()is called. The emit would look something like:var _this = _super.call(this)) || this;
so before this line,
_thisisundefined. any call to asupermethod is just sugar for_super.prototype.GetName.call(_this);and thus it needs to pass the value of_this. if this is done before_thisis defined it will fail at runtime.the rule the compiler should enforce is that
thisis never used (neither directly nor indirectly throughsuper) before thesuper()constructor call.Reacted by Elephant-Vessel and JedWe should definitely make this an error. Tested in NodeJS REPL:
> class B { constructor(o) {} getName() {} } [Function: B] > class C extends B { constructor() { super(super.getName()); } } [Function: C] > new C ReferenceError: this is not defined at C (repl:1:43)- locked and limited conversation to collaborators
on Jun 19, 2018
TypeScript Version: 2.1.1 and nightly (2.2.0-dev.20161205)
Code
Expected behavior: (As per 2.0.10 and Playground)
Actual behavior:
Notice the difference in the compiled call to
_super.GetName/_super.prototype.GetNamewhensuper.GetNameoccurs in the super-constructor, while calls to_super.GetNameoutside of the constructor always gets compiled to_super.prototype.GetName.GetName is always attached to the prototype, so the
_super.GetNameis breaking runtime.Is there an intention, which would make sense, to disallow calls to super until after the constructor is run, only allowing static calls? Nevertheless, the generated code don't make sense and no compiler error is shown.