TypeScript use dynamic imports in ES5 with Bluebird
I am trying to use a new dynamic import()
function in TypeScript, but I am getting the following error:
TS2712: Calling imports dynamically in ES5 / ES3 requires a "promise" constructor. Make sure you have a declaration for "Promise", a constructor, or include "ES2015" in your option
--lib
.
I could include the ES2015.promise
lib in my tsconfig as the post suggests, but that will make me lose type safety since I am using Bluebird promises.
I know it is possible to use Bluebird for async/await
in TypeScript, so I suppose this should work the same way too.
The post also mentions the following:
Make sure you have a declaration for the "Promise" constructor or [...]
Is it possible to declare a Bluebird constructor to be used as a Promise constructor in TS?
Sample 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"]
}
source to share
TypeScript looks for the global Promise
. What you have in your code is one Promise
declared in a module ("bluebird") and used locally in another module.
Here's a minimal way to fix compilation errors and having executable 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 changed the console.log
output-only statement $
so that the above code can be easily run in Node and not require a browser. (When you load jquery
into Node, you get a constructor that needs an instance Window
, from which you then instantiate the same type of object jquery
that you immediately get when loaded jquery
in a window. $.fn.jquery
Is not available.)
I am using the following tsconfig.json
which I got 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 of unnecessary options and skipLibCheck
needed to handle problems @types/jquery
.
source to share