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

Mei*_*hes 18 async-await typescript

我有一个异步生成器:

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

但是使用typescript 2.3,这给了我错误:

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

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

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

Mei*_*hes 34

Symbol.asyncIterator是一个esnext特色; 所以你必须明确目标esnext,或者添加esnext.asynciterable库,打字稿支持的语法.但是,typescript目前还没有在运行时处理Symbols的实现,所以你需要进行polyfill.

Polyfill + Down-Compile

加入"esnext.asynciterable"libtsconfig.json

{
  "compilerOptions": {
    "target": "es2015",
    "moduleResolution": "node",
    "module": "commonjs",
    "lib": [      
      "dom",
      "es2015",
      "esnext.asynciterable"
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

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

if(Symbol["asyncIterator"] === undefined) ((Symbol as any)["asyncIterator"]) = Symbol.for("asyncIterator");
Run Code Online (Sandbox Code Playgroud)

编译并正常运行.

这也应该应用在任何可重用的包中 - 理想情况是在模块main脚本的第一行

原生支持

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

target: "esnext"在tsconfig.json中设置,编译并运行

node --harmony_async_iteration example.js
Run Code Online (Sandbox Code Playgroud)

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

ts-node --harmony_async_iteration example.ts
Run Code Online (Sandbox Code Playgroud)

使用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"
Run Code Online (Sandbox Code Playgroud)