在 Typescript 中使用 AsyncIterator – 必需选项

Use AsyncIterator in Typescript – required options

考虑这个基本的 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 mentions several caveats, none of which could solve my problem. Oddly enough, iterating async generators 工作正常。

编译此示例需要哪些 tsconfig 选项?

进一步深入研究问题后,看来这是由多个问题引起的。

异步迭代器不能依赖其上下文(例如 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() 方法必须 始终 return 具有 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 });
      }
    };
  }
};