question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

No compile error thrown when `this` referenced before call to `super` completes

See original GitHub issue

TypeScript Version:

1.8.9

Code JSFiddle: https://jsfiddle.net/kitsonk/fs9t96ep/ TS Playground: http://goo.gl/X7cgvV

class A {
    constructor(fn: () => void) {
        fn.call(this);
    }
    foo: string = 'foo';
}

class B extends A {
    constructor() {
        super(() => {
            console.log(this);
        });
    }
    bar: string = 'bar';
}

const b = new B();

Expected behavior: Typescript should guard against the use of this as the call to super has not completed. Thus it should not compile.

Actual behavior: Typescript compiles this successfully. It works fine when the target is set to es5 but breaks the browser when target is set to es6. Error is: VM89:55 Uncaught ReferenceError: this is not defined

Issue Analytics

  • State:open
  • Created 7 years ago
  • Comments:13 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
zemlanincommented, Nov 19, 2016

One more case (https://gist.github.com/zemlanin/a306e8498d05c923cac405c047014029):

// this.ts
class A {
    constructor(protected cb: () => void) { }
}

class Greeter extends A {
    constructor() {
        // ^ there should be `var _this = this;`
        super(() => { this })
    }
}
// compiled_with_ts2_0_10.js
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var A = (function () {
    function A(cb) {
        this.cb = cb;
    }
    return A;
}());
var Greeter = (function (_super) {
    __extends(Greeter, _super);
    function Greeter() {
        var _this = this;
        // ^ there should be `var _this = this;`
        _super.call(this, function () { _this; });
    }
    return Greeter;
}(A));
// compiled_with_ts2_1_1.js
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var A = (function () {
    function A(cb) {
        this.cb = cb;
    }
    return A;
}());
var Greeter = (function (_super) {
    __extends(Greeter, _super);
    function Greeter() {
        return
        // ^ there should be `var _this = this;`
        _super.call(this, function () { _this; }) || this;
    }
    return Greeter;
}(A));
1reaction
kitsonkcommented, Nov 4, 2016

Just a note on this, the emit in master (TS 2.1) now breaks these examples in ES5 at run-time, so this now has parity. It still does not warn you that it is invalid.

Given:

class A {
    constructor(fn: () => void) {
        fn.call(this);
    }
    foo: string = 'foo';
}

class B extends A {
    constructor() {
        super(() => {
            console.log(this);
        });
    }
    bar: string = 'bar';
}

The emit is…

Version 2.1.0-dev.20161103

var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var A = (function () {
    function A(fn) {
        this.foo = 'foo';
        fn.call(this);
    }
    return A;
}());
var B = (function (_super) {
    __extends(B, _super);
    function B() {
        var _this = _super.call(this, function () {
            console.log(_this);
        }) || this;
        _this.bar = 'bar';
        return _this;
    }
    return B;
}(A));

Version 2.0.6

var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var A = (function () {
    function A(fn) {
        this.foo = 'foo';
        fn.call(this);
    }
    return A;
}());
var B = (function (_super) {
    __extends(B, _super);
    function B() {
        var _this = this;
        _super.call(this, function () {
            console.log(_this);
        });
        this.bar = 'bar';
    }
    return B;
}(A));
Read more comments on GitHub >

github_iconTop Results From Across the Web

Always allow code before super call when it does not use ...
The error message explains what went wrong precisely I think. This is fine: class MyClass { constructor(public str: string) { } } class ......
Read more >
Why do this() and super() have to be the first statement in a ...
(2) The compiler appears to implement a different check which is, by itself, sufficient to prevent this problem. The message is "cannot reference...
Read more >
Bug Patterns
AndroidInjection.inject() should always be invoked before calling super.lifecycleMethod(). ArrayEquals. Reference equality used to compare arrays.
Read more >
compile time error messages : Java Glossary
You are using a method of the object when the reference is to an interface that does not contain that method. Either cast...
Read more >
Exceptions and Error Handling, C++ FAQ
What does throw; (without an exception object after the throw keyword) mean? ... throw is to return a return code (sometimes called an...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found