I have a utility function which is a generator, like this:
function* myGenerator(): Generator<Foo, void> {
... // yield Foos
}
Now I want to wrap this utility function in a class, like this:
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.
I can remove the *
from MyWrapper.generator()
, have the return type be Generator<Foo, void>
, and return 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).
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?
CodePudding user response:
You can use yield*
to yield all elements of another generator
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"]