【问题标题】:How to yield* arrays in Typescript如何在 Typescript 中生成 * 数组
【发布时间】:2020-07-26 14:20:24
【问题描述】:

我有一个生成器方法,它可以将一些东西异步添加到数组中,最后生成带有yield* array 的每个成员,如下所示:

while (!done) {
      await promise;
      yield* results; //<-- the array
      results = [];  //its emptied so as to not to yield dupes
      done = !this.#eventsListened.has(eventName);
    }

但是我们友好的邻居 tsc 报告了一个错误,我什至无法理解它或如何修复它。谁能解释这个错误是什么意思,我应该如何产生一个数组的内容?

TS2766:无法将迭代委托给 value,因为“next”方法 其迭代器的期望类型为“未定义”,但包含的生成器 将始终发送“未知”。

编辑:整个生成器函数如下

  /**
   * Returns an iterator that loops over caught events
   * @yields Promise<Event|CustomEvent>
   */
  async *on(eventName: string, options?: AddEventListenerOptions): AsyncGenerator<Event> {
    if (this.#eventsListened.has(eventName)) {
      return;
    }
    let results: Event[] = [];

    let resolve: (value?: PromiseLike<Event> | Event) => void;

    let promise = new Promise<Event>(r => (resolve = r));
    let done = false;
    this.#eventsListened.add(eventName);

    if (typeof options === 'object' && typeof options.once !== 'undefined') {
      throw new Error('options.once is not supported. Use EventTarget2.once instead');
    }
    const callback = (evt: Event) => {
      results.push(evt);
      resolve();
      promise = new Promise<Event>(r => (resolve = r));
    };

    this.addEventListener('eventName', callback, options);
    while (!done) {
      await promise;
      yield* results;
      results = [];
      done = !this.#eventsListened.has(eventName);
    }
    this.removeEventListener(eventName, callback);
  }

【问题讨论】:

  • 您是真的要使用yield* 还是需要普通的yield
  • @VLAZ 我的意思是 yield* 我想单独产生数组的每个成员
  • 需要更多上下文(主要是function* 定义)。
  • 问题是.next(stuff) 会将一个值传递给迭代器,而yield* 也会传递给数组迭代器。数组迭代器的类型为Iterator&lt;void, T, undefined&gt;,因此您只能将其称为.next(),但是您的生成器函数的类型不同(或根本没有)。因此.next(...) 调用冲突。

标签: javascript arrays typescript async-await generator


【解决方案1】:

您的主要问题是AsyncGenerator&lt;Event&gt; ...由于您没有指定第三个通用参数,因此使用它的默认值(unknown),并且unknown 不匹配undefined

发生不匹配是因为内部迭代器不期望通过next(value) 传递给迭代器的任何值,因此它的TNext 泛型参数是undefined。当你 yield* 那个迭代器时,在你的生成器迭代器上调用 next(...) 将调用具有相同参数的内部迭代器,因此参数必须匹配。

Typescript 正是出于这个原因将生成器函数的类型推断为 AsyncGenerator&lt;..., ..., undefined&gt;,您也应该这样做(只要您不想使用 .next 将值传递给迭代器):AsyncGenerator&lt;Event, void, undefined&gt;

【讨论】:

  • 谢谢!那成功了……我不知道 AsyncGenerator 接口有三种类型。你可以向迭代器发送一个值仍然让我感到困惑。
猜你喜欢
  • 2018-04-27
  • 2021-11-11
  • 2021-09-17
  • 2016-08-07
  • 2022-06-25
  • 2023-03-20
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多