Typescript: Bug or breaking change in super constructors?

Created on 5 Dec 2016  路  6Comments  路  Source: microsoft/TypeScript

TypeScript Version: 2.1.1 and nightly (2.2.0-dev.20161205)

Code

abstract class Animal
{
    constructor(someStr) { }

    public GetName() {
        return "test";
    }
}

class Dog extends Animal
{
    constructor()
    {
        super(super.GetName());
        var test = super.GetName();
    }
}

Expected behavior: (As per 2.0.10 and Playground)

var Dog = (function (_super) {
    __extends(Dog, _super);
    function Dog() {
        _super.call(this, _super.prototype.GetName.call(this)); // <= Look here
        var test = _super.prototype.GetName.call(this);
    }
    return Dog;
}(Animal));

Actual behavior:

var Dog = (function (_super) {
    __extends(Dog, _super);
    function Dog() {
        var _this = _super.call(this, _super.GetName.call(_this)) || this; // <= Look here
        var test = _super.prototype.GetName.call(_this);
        return _this;
    }
    return Dog;
}(Animal));

Notice the difference in the compiled call to _super.GetName/_super.prototype.GetName when super.GetName occurs in the super-constructor, while calls to _super.GetName outside of the constructor always gets compiled to _super.prototype.GetName.

GetName is always attached to the prototype, so the _super.GetName is 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.

Bug High Priority

Most helpful comment

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. this is not defined until super() is called. The emit would look something like:

 var _this = _super.call(this)) || this;

so before this line, _this is undefined. any call to a super method is just sugar for _super.prototype.GetName.call(_this); and thus it needs to pass the value of _this. if this is done before _this is defined it will fail at runtime.

the rule the compiler should enforce is that this is never used (neither directly nor indirectly through super) before the super() constructor call.

All 6 comments

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
    }
}

Would 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. this is not defined until super() is called. The emit would look something like:

 var _this = _super.call(this)) || this;

so before this line, _this is undefined. any call to a super method is just sugar for _super.prototype.GetName.call(_this); and thus it needs to pass the value of _this. if this is done before _this is defined it will fail at runtime.

the rule the compiler should enforce is that this is never used (neither directly nor indirectly through super) before the super() constructor call.

We 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)
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Roam-Cooper picture Roam-Cooper  路  3Comments

bgrieder picture bgrieder  路  3Comments

remojansen picture remojansen  路  3Comments

kyasbal-1994 picture kyasbal-1994  路  3Comments

siddjain picture siddjain  路  3Comments