考虑基本的AsyncIterator Example from MDN:
var asyncIterable = {
[Symbol.asyncIterator]() {
return {
i: 0,
next() {
if (this.i < 3) {
return Promise.resolve({ value: this.i++, done: false });
}
return Promise.resolve({ done: true });
}
};
}
};
(async function() {
for await (let num of asyncIterable) {
console.log(num);
}
})();
在节点10.16.0上运行此命令正常。但是,我似乎无法使其通过Typescript运行。使用以下tsconfig:
{
"compilerOptions": {
"lib": ["es2016", "esnext.asynciterable"],
"target": "es2016"
}
}
导致错误The type returned by the 'next()' method of an async iterator must be a promise for a type with a 'value' property.
,与目标esnext
相同。
如果我完全删除target
选项,则会得到Type '{ [Symbol.asyncIterator](): { i: number; next(): Promise<{ done: boolean; }>; }; }' is not an array type or a string type.
TS manual提到了几个警告,但没有一个可以解决我的问题。奇怪的是,iterating async generators可以正常工作。
要编译此示例,需要哪些tsconfig选项?
答案 0 :(得分:1)
深入研究问题之后,似乎是由于这里存在多个问题。
异步迭代器不能依赖其上下文(例如this.i
)来访问不属于AsyncIterator
接口的属性。这样做将无法在当前版本的TypeScript 3.6中进行编译(即使它在JavaScript中也可以正常工作),因此要解决此问题,我们只剩下:
var asyncIterable = {
[Symbol.asyncIterator]() {
let i = 0;
return {
next() {
if (i < 3) {
return Promise.resolve({ value: i++, done: false });
}
return Promise.resolve({ done: true });
}
};
}
};
现在问题似乎与第二个return语句中缺少value
有关。因为IteratorResult
接口的定义如下:
interface IteratorResult<T> {
done: boolean;
value: T;
}
next()
方法必须始终返回带有value: number
的对象(同样,即使它在JavaScript中也可以正常工作),所以最终我们有了:
var asyncIterable = {
[Symbol.asyncIterator]() {
let i = 0;
return {
next() {
if (i < 3) {
return Promise.resolve({ value: i++, done: false });
}
return Promise.resolve({ value: i, done: true });
}
};
}
};