Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async / await with Bluebird promises #8331

Closed
jjrv opened this issue Apr 27, 2016 · 6 comments
Closed

Async / await with Bluebird promises #8331

jjrv opened this issue Apr 27, 2016 · 6 comments

Comments

@jjrv
Copy link

jjrv commented Apr 27, 2016

In TypeScript 1.9.0-dev.20160426 I tried:

import * as Promise from 'bluebird';

async function test() {
    await Promise.delay(1000);
}

test();

The compiler reports:

error TS2529: Duplicate identifier 'Promise'. Compiler reserves name 'Promise' in top level scope of a module containing async functions.

Especially since this is purely for Node.js, I'd like to use Bluebird promises for their debuggability and import them as Promise instead of some other name.

Could I provide my own __awaiter or could the default one use the imported Promise?

@yortus
Copy link
Contributor

yortus commented Apr 27, 2016

See #6631 which describes the rationale for reserving the identifier Promise. The issue that prompted that PR has a lot of related discussion, starting around here. Personally I would have preferred another way of of solving the problem without reserving Promise since it breaks a lot of existing code such as yours (my reasons were stated here).

@jjrv
Copy link
Author

jjrv commented Apr 27, 2016

Thanks! I see that it's unlikely the current behavior would change then... Closing.

@jjrv jjrv closed this as completed Apr 27, 2016
@jjrv
Copy link
Author

jjrv commented Apr 27, 2016

This is horrible but compiles and seems to work:

bluebird-shim.d.ts:

import * as Bluebird from 'bluebird';

export interface DummyConstructor extends Bluebird<any> {
    new<T>(): Bluebird<T>;
    all: any;
    race: any;
}

declare global {
    interface Promise<T> extends Bluebird<T> {}

    interface PromiseConstructor extends DummyConstructor {}
}

Test code:

import * as Bluebird from 'bluebird';

Promise = Bluebird as any;

async function test() {
    console.log('Waiting...');

    await Promise.delay(1000);

    console.log('Done!');
}

test();

Not sure if this is actually valid and whether redefining __awaiter is necessary. Will this break in ES7 (I'm guessing yes)?

@jjrv
Copy link
Author

jjrv commented Apr 27, 2016

Maybe I'll reopen this to have the above questions looked at, in case others run into the same issue.

@jjrv jjrv reopened this Apr 27, 2016
@yortus
Copy link
Contributor

yortus commented Apr 27, 2016

Actually this simpler version compiles and runs fine:

Promise = require('bluebird');

async function test() {
    await Promise.delay(1000);
}

test();

It simply assigns to the global Promise, avoiding the Duplicate identifier 'Promise' error. And bluebird's ambient Promise declarations already merge with the ES6 ones, so that things like delay are defined.

If you look at the emitted JavaScript, the builtin __awaiter function will then use this bluebird Promise constructor for the async function, despite #6631 which aimed to ensure that async functions always used the ES6 Promise in line with the ES spec.

Since a compliant runtime will always use ES6 Promises for async functions, even if the global Promise identifier has been re-assigned, the above code behaves differently to how it would run directly without downlevelling (e.g. in the Edge browser which natively supports async/await).

@jjrv
Copy link
Author

jjrv commented Apr 27, 2016

@yortus Thanks! I've been using typed-typings/npm-bluebird which seems to require the above shim.

I guess the conclusion is that there's several ways around the new stricter native ES6 promise requirement, and as long as the code is transpiled to ES6 instead of ES7, it should run the same on all platforms that support generators/yield. Targeting ES7 will break every possible hack.

@jjrv jjrv closed this as completed Apr 27, 2016
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants