TS2318:找不到全局类型' AsyncIterableIterator' - 异步发生器

时间:2017-04-29 10:06:24

标签: typescript async-await

我有一个异步生成器:

async function* foo() {
  yield "wait...";
  await new Promise(r=>setTimeout(r, 900));
  yield new Promise(r=>setTimeout(()=>r("okay!"), 100));
}

async function main() {
  for await (let item of foo()) {
    let result = await item;
    console.log(result);
  }
}

main();

但是使用打字稿2.3这给了我错误:

  

错误TS2318:找不到全局类型' AsyncIterableIterator'。   example.ts(10,26):

     

错误TS2504:类型必须有' Symbol.asyncIterator'返回异步迭代器的方法。

如何修复此错误以及如何运行异步生成器?

1 个答案:

答案 0 :(得分:25)

Symbol.asyncIteratoresnext功能;因此,您必须明确定位esnext添加esnext.asynciterable库,以获取支持语法的typescript。但是,typescript目前在运行时处理符号的实现,所以你需要进行polyfill。

Polyfill + Down-Compile

"esnext.asynciterable"

中将lib添加到tsconfig.json
{
  "compilerOptions": {
    "target": "es2015",
    "moduleResolution": "node",
    "module": "commonjs",
    "lib": [      
      "dom",
      "es2015",
      "esnext.asynciterable"
    ]
  }
}

您可以在执行任何其他操作之前简单地创建新符号来填充Symbol.asyncIterator

if(Symbol["asyncIterator"] === undefined) ((Symbol as any)["asyncIterator"]) = Symbol.for("asyncIterator");

正常编译并运行。

这也适用于任何可重复使用的软件包 - 最好是在模块的第一行main脚本

原生支持

如果您的目标是节点7及更高版本,您实际上可以使用标志本机运行异步迭代器。

在tsconfig.json中设置target: "esnext",编译并使用

运行
node --harmony_async_iteration example.js

同样可用于ts节点,您可以在其中直接运行它。

ts-node --harmony_async_iteration example.ts

使用Node 9;它已在--harmony标志

下进行

从节点10开始;它默认启用。

警告:

当你将打包的async-gen代码与babel的webpack包中的down-compile混合时,我遇到了一些兼容性问题。 可能应该是babel的polyfill如何查找符号,然后如果缺少则创建一个符号。兼容性问题是,看起来babel代码并不认为typescript(+ Symbol polyfill)代码具有Symbol.asyncIterable密钥条目。

也可以使用babel插件将使用的相同符号polyfill来避免此问题:

import "core-js/modules/es7.symbol.async-iterator"