问题
I'm trying to use the new dynamic import() function in TypeScript, but I get the following error:
TS2712: A dynamic import call in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your
--liboption.
I could include the ES2015.promise lib in my tsconfig like the message suggests, but that would make me lose type safety as I'm using Bluebird promises.
I know it is possible to use Bluebird for async/await in TypeScript, so I suppose this should also work the same way.
The message also mentions this:
Make sure you have a declaration for the 'Promise' constructor or [...]
Is it possible to declare the Bluebird constructor to be used as the Promise constructor in TS?
Example code:
import * as Bluebird from 'bluebird';
// This works
async function exampleAsync(): Bluebird<number> {
const result = await Bluebird.resolve(5);
return result;
}
// This does not
import('jquery').then($ => {
console.log($.fn.jquery);
});
TSConfig:
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"removeComments": true,
"sourceMap": true,
"alwaysStrict": true,
"forceConsistentCasingInFileNames": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strictNullChecks": true,
"allowJs": true,
"typeRoots": ["node_modules/@types"],
"lib": ["es5", "dom", "es2015.collection"]
},
"exclude": ["node_modules"]
}
回答1:
TypeScript is looking for a global Promise. What you have in your code is a Promise declared in a module ("bluebird") and used locally in another module.
Here's a minimal way to get the compilation errors to be resolve and to have runnable code:
test.ts:
import * as Bluebird from 'bluebird';
declare global {
const Promise: {
new <R>(callback: (
resolve: (thenableOrResult?: R | PromiseLike<R>) => void,
reject: (error?: any) => void,
onCancel?: (callback: () => void) => void
) => void): Bluebird<R>;
};
}
import('jquery').then($ => {
console.log($);
});
I've modified the console.log statement to just output $ so that the code above can be readily run in Node rather than require a browser. (When you load jquery in Node, you get a constructor that needs a Window instance from which you then build the same kind of jQuery object you immediately get when you load jquery in a window. So $.fn.jquery is not accessible.)
I'm using the following tsconfig.json which I derived from yours:
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"removeComments": true,
"sourceMap": true,
"alwaysStrict": true,
"forceConsistentCasingInFileNames": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strictNullChecks": true,
"allowJs": true,
"skipLibCheck": true,
"lib": ["es5", "dom", "es2015.collection"]
}
}
You had a couple unnecessary options in there, and skipLibCheck is necessary to handle issues @types/jquery.
来源:https://stackoverflow.com/questions/45171651/typescript-promise-constructor-declaration