【问题标题】:Properly typing a generator function that calls another generator function in TypeScript在 TypeScript 中正确键入调用另一个生成器函数的生成器函数
【发布时间】:2021-12-28 07:11:15
【问题描述】:

我有一个实用函数,它是一个生成器,如下所示:

function* myGenerator(): Generator<Foo, void> {
  ... // yield Foos
}

现在我想将这个实用函数包装在一个类中,如下所示:

class MyWrapper {
  *generator(): Generator<Foo, void> {
    // call utils.myGenerator();
  }
}

问题是:如果我输入MyWrapper.generator() 作为带有* 符号的生成器,我不能简单地将它实现为return utils.myGenerator(),因为生成器函数返回 void,我会得到一个Type Generator&lt;Foo, void&gt; is not assignable to void 错误。

我可以从MyWrapper.generator() 中删除*,返回类型为Generator&lt;Foo, void&gt;,并返回utils.myGenerator()

class MyWrapper {
  generator(): Generator<Foo, void> {
    return utils.myGenerator();
  }
}

...但是丢失* 使调用者不太清楚这是一个生成器函数(当然,返回类型应该放弃它,但仍然如此)。

我还可以遍历“内部”生成器并从中生成所有内容:

class MyWrapper {
  *generator(): Generator<Foo, void> {
    for (const x of utils.myGenerator()) {
      yield x;
    }
  }
}

...但是这个额外的屈服层看起来很傻。

我是否缺少一种明显的方法来让一个生成器函数包装另一个生成器函数并仍然保持* 表示法,例如“yield all from”语法?

【问题讨论】:

    标签: javascript typescript generator


    【解决方案1】:

    您可以使用yield* 来生成另一个生成器的所有元素

    type Foo = string
    function* myGenerator(): Generator<Foo, void> {
        yield "A";
        yield "B";
    }
    
    
    class MyWrapper {
      *generator(): Generator<Foo, void> {
        yield* myGenerator();
      }
    }
    
    console.log([...new MyWrapper().generator()]) // ["A", "B"] 
    

    Playground Link

    【讨论】:

    • 看,这就是我所追求的,我知道有一种方法可以“放弃所有”,但它在我的脑海中太遥远了。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2012-07-15
    • 2016-01-09
    • 2019-06-08
    • 2021-09-17
    相关资源
    最近更新 更多