TypeScript 在带有 Bluebird 的 ES5 中使用动态导入

TypeScript use dynamic import in ES5 with Bluebird

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

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.

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

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


留言中也提到了这一点:

Make sure you have a declaration for the 'Promise' constructor or [...]

是否可以在 TS 中声明 Bluebird 构造函数作为 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);
});

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"]
}

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($);
});

我已将 console.log 语句修改为仅输出 $ 以便上面的代码可以很容易地 运行 在 Node 中而不需要浏览器。 (当你在 Node 中加载 jquery 时,你会得到一个构造函数,它需要一个 Window 实例,然后你可以从中构建相同类型的 jQuery 对象,当你加载 jquery 在 window 中。所以 $.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"]
  }
}

你有几个不必要的选项,skipLibCheck 是处理问题所必需的 @types/jquery