Skip to content

Wrong async scope resolution #30066

Closed
@gabrielbiga

Description

@gabrielbiga

TypeScript Version: 3.4.0-dev.20190223

Search Terms: Async, Await, Decorator, _superIndex

Code

interface IOnInit {
    onInit(): Promise<void>;
}

class Emitter {
    public on(fn: Function) { fn(); }
}

function MyDecorator() {
    return <T extends { new(...args: Array<any>): Object }>(target: T) => {
        return class extends target implements IOnInit {
            protected emitter = new Emitter();

            public async onInit(): Promise<void> {
                this.emitter.on(async () => {
                    if (super['onInit']) await super['onInit']();

                    console.log('exec');
                });
            }
        };
    }
}

@MyDecorator()
class Main implements IOnInit {
    async onInit() {
        console.log('Main INIT!');
    }
}

new Main().onInit();

Build command line:

tsc --experimentalDecorators true --target es6 test.ts  && node test.js

Expected behavior:
Print on the console:

Main INIT!
exec

Note: It is working on TS 2.9.2.

Actual behavior:
It throws this stacktrace on console:

(node:30260) UnhandledPromiseRejectionWarning: ReferenceError: _superIndex is not defined
    at Object.<anonymous> (/home/gabriel/Documents/test_ts_bug/test.js:29:25)
    at Generator.next (<anonymous>)
    at /home/gabriel/Documents/test_ts_bug/test.js:12:71
    at new Promise (<anonymous>)
    at __awaiter (/home/gabriel/Documents/test_ts_bug/test.js:8:12)
    at emitter.on (/home/gabriel/Documents/test_ts_bug/test.js:28:43)
    at Emitter.on (/home/gabriel/Documents/test_ts_bug/test.js:16:14)
    at Object.<anonymous> (/home/gabriel/Documents/test_ts_bug/test.js:28:34)
    at Generator.next (<anonymous>)
    at /home/gabriel/Documents/test_ts_bug/test.js:12:71

Looking at the source code, the compiler isn't generating the _superIndex arrow function.

Changing the code of the onInit() function, it corrects the issue:

const parentOnInit = super['onInit'];

this.emitter.on(async () => {
    if (parentOnInit) await parentOnInit();

    console.log('exec');
});

Playground Link: Not reproducible on the playground, because it just throws when compiling to ES6.

Related Issues: Did not found other similar bug. Maybe related to #26707?

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions