Typescript: Arrow functions don't work in super calls

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

Typescript version: 2.1.4

Playground: https://www.typescriptlang.org/play/index.html#src=class%20C%20%7B%0D%0A%09constructor(public%20f%3A%20%7B%20()%3A%20string%20%7D)%20%7B%0D%0A%0D%0A%09%7D%0D%0A%0D%0A%09%0D%0A%7D%0D%0A%0D%0Aclass%20B%20extends%20C%20%7B%0D%0A%09constructor()%20%7B%0D%0A%09%09super(()%20%3D%3E%20%7B%20return%20this.g()%3B%20%7D)%0D%0A%09%7D%0D%0A%0D%0A%09private%20g()%20%7B%0D%0A%09%09return%20%22hello%22%3B%0D%0A%09%7D%0D%0A%7D%0D%0A%0D%0Aalert(new%20B().f())%3B

Source:

class C {
    constructor(public f: { (): string }) {
    }   
}

class B extends C {
    constructor() {
        super(() => { return this.g(); })
    }

    private g() {
        return "hello";
    }
}

alert(new B().f());

Expected result: "Hello" is alerted.
Actual result: calling f() fails with referenceerror.

The problem is that arrow functions are bound by the use of _this. Unfortunately, when there is a super call with no other this references, Typescript skips emitting the _this variable. _this doesn't exist so when the function is called, it fails.

If somehow this is the intended behaviour, the compiler should error on this references in super calls.

Bug Fixed High Priority

Most helpful comment

Fix should be in [email protected] or later.

All 6 comments

I guess there should be an error, because super must be called before accessing this.
Just change constructor of B to code below and you will get error (the code is equal)

super(this.g.bind(this));

This is basically working as intended because we have no way to know that the base class constructor invokes the function immediately. If instead the base class constructor stored a reference to the closure and then invoked it later (for example, maybe this function is an event handler), no error would occur and the code is fine.

I don't understand? The base class constructor does do exactly that in my sample- it stores the reference and then it is called later. But the error still occurs.

Sorry, misread. You're right - we should have emitted var _this = this; above the super call

Just for reference, it seems to me that even if the base class invokes the callback immediately, that should be safe as long as it doesn't return a new value for this?

Fix should be in [email protected] or later.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

manekinekko picture manekinekko  路  3Comments

bgrieder picture bgrieder  路  3Comments

kyasbal-1994 picture kyasbal-1994  路  3Comments

CyrusNajmabadi picture CyrusNajmabadi  路  3Comments

seanzer picture seanzer  路  3Comments