I had the following code:
function asyncFunc1(): Promise<string> {
return new Promise<string>(x => x);
}
which produced the following error:
TS2304: cannot find name 'Promise'
So I changed it to explicitly declare 'Promise':
///<reference path="../typings/modules/bluebird/index.d.ts" />
import * as Promise from 'bluebird';
function asyncFunc1(): Promise<string> {
return new Promise<string>(x => x);
}
and now I get the following error:
TS2529: Duplicate identifier 'Promise'. Compiler reserves name
'Promise' in top level scope of a module containing async functions
How can I solve this paradox?
Promises are only available in ES6
If you set the target to ES6, the typescript compiler uses a different base library to for basic type checking against types included in the language specification. Make sure you are targeting ES6.
Promises in TypeScript without Targeting ES6
If you want access to definition of Constructors as methods defined in the es2015 specification, that have been implemented by browsers and NodeJS (via V8 engine) before language features - like arrow functions, destructuring, etc - you can do that.
What you want to do is configure TypeScript to target es5, not include and default library, and reference the default library yourself.
Your tsconfig might look something like this:
{
"compilerOptions: {
"noLib": true,
"target": "ES5",
}
"files": [
"node_modules/typescript/lib/lib.es6.d.ts",
"app.ts",
]
}
The above examples assumes that typescript is installed directly in your project. If it is not you can always copy from your typescript installation's folder and include it in your project.
This solution should give you typings for the Promise constructor, as well as a variety of other features like array.includes() and a few other things. This comes with the downside that you won't get type errors for things that are not implemented in the browsers, but if you're using Promise anyway you're probably targeting modern-browsers only, or you're using Node where you control the runtime environment.
It seems TypeScript is protecting the Promise identifier. Try importing as a name other than Promise, or use a different set of typings. There are a few suggestions in this TypeScript GitHub issue.
Async / await with Bluebird promises
The issue is regarding the use of a different promise library with Async Await, but this very situation is likely why they are protecting the Promise name. Specifically, when we use Async/Await in TypeScript the compiler converts this to a Promise in the emitted code, so the compiler is trying to protect the Promise constructor from being over-written. You can always trick the compiler with this sort of thing, but be sure to ask yourself if it's the right thing to do.