Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

typescript - TS2318: Cannot find global type 'AsyncIterableIterator' - async generator

I have an async generator:

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

but with typescript 2.3 this give me errors:

error TS2318: Cannot find global type 'AsyncIterableIterator'. example.ts(10,26):

error TS2504: Type must have a 'Symbol.asyncIterator' method that returns an async iterator.

How can this error be fixed and how can you run the async generator?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Symbol.asyncIterator is an esnext feature; so you must explicitly target esnext, or add the esnext.asynciterable library, for typescript to support the syntax. However, typescript does not deal with the implementation of Symbols at runtime at present, so you need to polyfill.

Polyfill + Down-Compile

Add "esnext.asynciterable" to lib in tsconfig.json

{
  "compilerOptions": {
    "target": "es2015",
    "moduleResolution": "node",
    "module": "commonjs",
    "lib": [      
      "dom",
      "es2015",
      "esnext.asynciterable"
    ]
  }
}

you can polyfill Symbol.asyncIterator by simply creating a new Symbol before you do anything else.

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

Compile and run as normal.

This should also be applied in any reusable packages - ideally on the very first line of your module's main script

Native Support

If you are targetting node 7 and above, you can actually just run async iterators natively with a flag.

Set target: "esnext" in tsconfig.json, compile, and run with

node --harmony_async_iteration example.js

Same is available for ts-node too, where you can run it directly.

ts-node --harmony_async_iteration example.ts

With Node 9; it has been staged under the --harmony flag

As of Node 10; it is enabled by default.

Warning:

I've experienced some compatibility issues when you mix typescript compiled async-gen code with babel's down-compile in a webpack bundle. It may be due how babel's polyfill looks for the symbol and then creates one if it is missing. The compatibility issue is that it would appear the babel code doesn't think the typescript (+Symbol polyfill) code has a Symbol.asyncIterable key-entry.

Could also avoid the problem by using the same Symbol polyfill that babel's plugin will use:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.8k users

...