问题描述
我有一个异步生成器:
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();
但是使用 typescript 2.3 这会给我错误:
but with typescript 2.3 this give me errors:
错误 TS2318:找不到全局类型AsyncIterableIterator".示例.ts(10,26):
错误 TS2504:类型必须具有返回异步迭代器的Symbol.asyncIterator"方法.
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?
推荐答案
Symbol.asyncIterator
是一个 esnext
特性;所以你必须明确定位esnext
,或添加esnext.asynciterable
库,以便打字稿支持语法.但是,typescript目前不在运行时处理Symbols的实现,所以需要polyfill.
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.
将 "esnext.asynciterable"
添加到 tsconfig.json
{
"compilerOptions": {
"target": "es2015",
"moduleResolution": "node",
"module": "commonjs",
"lib": [
"dom",
"es2015",
"esnext.asynciterable"
]
}
}
您可以通过在执行任何其他操作之前简单地创建一个新 Symbol 来填充 Symbol.asyncIterator
.
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");
正常编译和运行.
这也应该应用于任何可重用的包 - 最好在模块的 main
脚本的第一行
This should also be applied in any reusable packages - ideally on the very first line of your module's main
script
如果您的目标是节点 7 及更高版本,您实际上可以使用标志在本机运行异步迭代器.
If you are targetting node 7 and above, you can actually just run async iterators natively with a flag.
在tsconfig.json中设置target: "esnext"
,编译运行
Set target: "esnext"
in tsconfig.json, compile, and run with
node --harmony_async_iteration example.js
同样适用于 ts-node,你可以直接运行它.
Same is available for ts-node too, where you can run it directly.
ts-node --harmony_async_iteration example.ts
使用节点 9;它已在 --harmony
标志下上演
With Node 9; it has been staged under the --harmony
flag
从节点 10 开始;它默认启用.
As of Node 10; it is enabled by default.
当你在 webpack 包中混合使用 typescript 编译的异步生成代码和 babel 的向下编译时,我遇到了一些兼容性问题.可能是由于 babel 的 polyfill 如何查找符号,然后在缺少符号时创建一个.兼容性问题是 babel 代码似乎不认为打字稿(+Symbol polyfill)代码具有 Symbol.asyncIterable
键条目.
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.
也可以通过使用 babel 插件将使用的相同 Symbol polyfill 来避免这个问题:
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"
这篇关于TS2318:找不到全局类型“AsyncIterableIterator"-异步生成器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!