【问题标题】:TypeScript Promise TS2304 TS2529TypeScript Promise TS2304 TS2529
【发布时间】:2017-02-18 21:54:29
【问题描述】:

我有以下代码:

function asyncFunc1(): Promise<string> {
    return new Promise<string>(x => x);
}

产生以下错误:

TS2304:找不到名称“承诺”

所以我把它改成明确声明'Promise':

///<reference path="../typings/modules/bluebird/index.d.ts" />

import * as Promise from 'bluebird';

function asyncFunc1(): Promise<string> {
    return new Promise<string>(x => x);
}

现在我收到以下错误:

TS2529:重复的标识符“Promise”。编译器保留名称 包含异步函数的模块的顶级范围内的“承诺”

我该如何解决这个悖论?

【问题讨论】:

  • tsconfig 中的 compilerOptions.target 是什么?
  • @Paarth 我的目标是 es5
  • 你是否安装了任何其他定义 Promise 的模块,例如 core-js 或 es6-promise?
  • 该错误表明 Promise 被 TypeScript 保留。您是否尝试过导入 import * as Bluebird from 'bluebird'; 并将其用作 function asyncFunc1(): Bluebird&lt;string&gt;
  • @Catalyst 我真的不需要 Blubird。我添加它以消除第一个错误:TS2304:找不到名称'Promise'。请再仔细阅读我的问题。

标签: javascript typescript promise


【解决方案1】:

TypeScript 似乎在保护 Promise 标识符。尝试以 Promise 以外的名称导入,或使用不同的类型。在这个 TypeScript GitHub 问题中有一些建议。

Async / await with Bluebird promises

问题在于在 Async Await 中使用不同的 Promise 库,但这种情况很可能是他们保护 Promise 名称的原因。具体来说,当我们在 TypeScript 中使用 Async/Await 时,编译器会将其转换为发出代码中的 Promise,因此编译器试图保护 Promise 构造函数不被覆盖。你总是可以用这种事情来欺骗编译器,但一定要问问自己这样做是否正确。

【讨论】:

  • 我真的不需要 Blubird。我添加它以消除第一个错误:TS2304:找不到名称“Promise”。请再仔细阅读我的问题。
  • 那你需要定位es6。
  • 或者你可以半途而废,使用 es6 库声明,但以 es5 语言特性为目标。
【解决方案2】:

Promises 仅在 ES6 中可用

如果您将目标设置为 ES6,typescript 编译器将使用不同的基础库来针对语言规范中包含的类型进行基本类型检查。确保你的目标是 ES6。

不针对 ES6 的 TypeScript 中的承诺

如果您想访问构造函数的定义作为 es2015 规范中定义的方法,这些方法已在语言功能(如箭头函数、解构等)之前由浏览器和 NodeJS(通过 V8 引擎)实现 - 您可以这样做。

您要做的是将TypeScript配置为以es5为目标,而不是包含和默认库,并自己引用默认库。

您的 tsconfig 可能如下所示:

{
  "compilerOptions: {
    "noLib": true,
    "target": "ES5",
    }
   "files": [
     "node_modules/typescript/lib/lib.es6.d.ts",
     "app.ts",
   ]
}

以上示例假设 typescript 直接安装在您的项目中。如果不是,您可以随时从您的 typescript 安装文件夹中复制并将其包含在您的项目中。

这个解决方案应该为您提供 Promise 构造函数的类型,以及各种其他功能,如 array.includes() 和其他一些东西。这样做的不利之处在于,对于未在浏览器中实现的内容,您不会收到类型错误,但如果您仍然使用 Promise,您可能只针对现代浏览器,或者您使用的是您可以控制的 Node运行时环境。

【讨论】:

  • 感谢您一直帮助我。由于您没有标记我(@Alon),因此我没有收到您的 cmets 通知您之前的答案。我会告诉你我必须将我的项目定位到 ES6。希望您能找到适合我的限制的另一种解决方案:-)
  • @Alon 等等,所以你的目标是 ES6 并且你还没有可用的 Promise?您是否已经在使用 --no-lib 编译器选项?
  • 好的,我想通了。当我发布这个问题时,我正在转换为 ES5。然后出于另一个原因,我转向 ES6,我没有 TS2304,而是 TS2529,因为我添加了“从 Bluebird 导入”,所以我没有注意到它已经解决了我的错误。现在,在你明确地询问它之后,发现迁移到 ES6 也解决了这个错误。
  • 编辑:我在答案中添加了一条注释以检查语言目标。
猜你喜欢
  • 1970-01-01
  • 2020-03-21
  • 2017-06-23
  • 2018-02-25
  • 2019-10-07
  • 2016-12-29
  • 2023-02-15
  • 2015-09-19
  • 2019-12-19
相关资源
最近更新 更多