TypeScript 在 ES5 中与 Bluebird 一起使用动态导入

Dun*_*Luk 3 javascript promise typescript ecmascript-6 bluebird

我尝试import()在 TypeScript 中使用新的动态函数,但出现以下错误:

TS2712: ES5/ES3 中的动态导入调用需要“Promise”构造函数。确保您有“Promise”构造函数的声明或在您的--lib选项中包含“ES2015”。

我可以ES2015.promise像消息所建议的那样将库包含在我的 tsconfig 中,但这会让我失去类型安全性,因为我使用的是 Bluebird Promise。

我知道可以async/await在 TypeScript 中使用 Bluebird,所以我想这也应该以同样的方式工作。


邮件中还提到了这一点:

确保您有“Promise”构造函数的声明或[...]

是否可以声明 Bluebird 构造函数用作 TS 中的 Promise 构造函数?


示例代码:

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);
});
Run Code Online (Sandbox Code Playgroud)

TS配置:

{
  "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"]
}
Run Code Online (Sandbox Code Playgroud)

Lou*_*uis 5

TypeScript 正在寻找一个全局的 Promise. 您的代码中的内容是Promise在模块(“bluebird”)中声明的,并在另一个模块中本地使用的。

这是解决编译错误并获得可运行代码的最小方法:

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($);
});
Run Code Online (Sandbox Code Playgroud)

我已将console.log语句修改为仅输出$,以便上面的代码可以轻松在 Node 中运行,而不需要浏览器。(当您jquery在 Node 中加载时,您将获得一个构造函数,该构造函数需要一个Window实例,然后您可以从中构建与在窗口中jQuery加载时立即获得的相同类型的对象。因此无法访问。)jquery$.fn.jquery

我正在使用tsconfig.json从你的衍生而来的以下内容:

{
  "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"]
  }
}
Run Code Online (Sandbox Code Playgroud)

您在那里有一些不必要的选项,并且skipLibCheck是处理问题所必需的@types/jquery