Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
978 views
in Technique[技术] by (71.8m points)

javascript - TypeScript use dynamic import in ES5 with Bluebird

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 --lib option.

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"]
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...