Website-Suche

typescript - TS2318: globalen Typ ‚AsyncIterableIterator‘ nicht gefunden - asynchroner Generator


Ich habe einen asynchronen 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();

aber mit TypeScript 2.3 gibt mir das Fehler:

Fehler TS2318: Globaler Typ 'AsyncIterableIterator' kann nicht gefunden werden. example.ts(10,26):

Fehler TS2504: Typ muss eine 'Symbol.asyncIterator'-Methode haben, die einen asynchronen Iterator zurückgibt.

Wie kann dieser Fehler behoben werden und wie kann man den asynchronen Generator ausführen?

Antwort #1

Symbol.asyncIterator ist ein esnext-Feature; daher müssen Sie explizit esnext als Ziel angeben oder die Bibliothek esnext.asynciterable hinzufügen, damit TypeScript die Syntax unterstützt. TypeScript kümmert sich jedoch derzeit nicht um die Implementierung von Symbolen zur Laufzeit, daher müssen Sie ein Polyfill verwenden.

Polyfill + Herunterkompilieren

Fügen Sie "esnext.asynciterable" zu lib in tsconfig.json hinzu

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

Sie können Symbol.asyncIterator polyfillen, indem Sie einfach ein neues Symbol erstellen, bevor Sie irgendetwas anderes tun.

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

Kompiliere und führe wie gewohnt aus.

Dies sollte auch auf alle wiederverwendbaren Pakete angewendet werden - idealerweise in der allerersten Zeile des main-Skripts Ihres Moduls

Native-Unterstützung

Wenn Sie Node 7 und höher anvisieren, können Sie asynchrone Iteratoren tatsächlich einfach nativ mit einem Flag ausführen.

Setze target: "esnext" in tsconfig.json, kompiliere und führe aus mit

node --harmony_async_iteration example.js

Das Gleiche ist auch für ts-node verfügbar, wo Sie es direkt ausführen können.

ts-node --harmony_async_iteration example.ts

Mit Node 9; es wurde unter dem --harmony-Flag bereitgestellt

Ab Node 10; es ist standardmäßig aktiviert.

Warnung :

Ich habe einige Kompatibilitätsprobleme festgestellt, wenn man mit TypeScript kompilierte async-gen Codes mit Babelf Down-Compile in einem Webpack-Bundle mischt. Es könnte daran liegen, wie Babelfs Polyfill nach dem Symbol sucht und dann eines erstellt, falls es fehlt. Das Kompatibilitätsproblem besteht darin, dass es so aussieht, als würde der Babel-Code nicht denken, dass der TypeScript (+ Symbol-Polyfill) Code einen Symbol.asyncIterable-Eintrag hat.

Man könnte das Problem auch vermeiden, indem man denselben Symbol-Polyfill verwendet, den das Babel-Plugin verwenden wird:

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

Verwandte Artikel