简体   繁体   English

正确键入在 TypeScript 中调用另一个生成器 function 的生成器 function

[英]Properly typing a generator function that calls another generator function in TypeScript

I have a utility function which is a generator, like this:我有一个实用程序 function 是一个生成器,如下所示:

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

Now I want to wrap this utility function in a class, like this:现在我想将这个实用程序 function 包装在 class 中,如下所示:

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

The problem is: If I type MyWrapper.generator() as a generator with the * notation, I cannot simply implement it as return utils.myGenerator() , because a generator function returns void, and I will get a Type Generator<Foo, void> is not assignable to void error.问题是:如果我输入MyWrapper.generator()作为带有*符号的生成器,我不能简单地将其实现为return utils.myGenerator() ,因为生成器 function返回void,我将得到一个Type Generator<Foo, void> is not assignable to void错误。

I can remove the * from MyWrapper.generator() , have the return type be Generator<Foo, void> , and return utils.myGenerator() :我可以从MyWrapper.generator()中删除* ,返回类型为Generator<Foo, void> ,然后返回utils.myGenerator()

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

... but losing * makes it less clear for the caller that this is a generator function (granted, the return type should give it away, but still). ...但是丢失*使调用者不太清楚这是一个生成器 function (当然,返回类型应该放弃它,但仍然如此)。

I can also iterate through the "inner" generator and yield everything from it:我还可以遍历“内部”生成器并从中产生所有内容:

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

... but this extra yielding layer seems silly. ...但是这个额外的屈服层似乎很愚蠢。

Is there an obvious way I'm missing to have a generator function wrap another generator function and still maintain the * notation, such as a "yield everything from" syntax?有没有一种明显的方法我缺少一个生成器 function 包装另一个生成器 function 并仍然保持*表示法,例如“yield everything from”语法?

You can use yield* to yield all elements of another generator您可以使用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 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM