Tengo una función de utilidad que es un generador, así:
function* myGenerator(): Generator<Foo, void> { ... // yield Foos }Ahora quiero envolver esta función de utilidad en una clase, así:
class MyWrapper { *generator(): Generator<Foo, void> { // call utils.myGenerator(); } } El problema es: si MyWrapper.generator() como un generador con la notación * , no puedo simplemente implementarlo como return utils.myGenerator() , porque una función de generador devuelve void, y obtendré un Type Generator<Foo, void> is not assignable to void error.
Puedo eliminar el * de MyWrapper.generator() , hacer que el tipo de devolución sea Generator<Foo, void> y devolver utils.myGenerator() :
class MyWrapper { generator(): Generator<Foo, void> { return utils.myGenerator(); } } ... pero perder * hace que sea menos claro para la persona que llama que se trata de una función generadora (por supuesto, el tipo de retorno debería revelarlo, pero aún así).
También puedo iterar a través del generador "interno" y obtener todo de él:
class MyWrapper { *generator(): Generator<Foo, void> { for (const x of utils.myGenerator()) { yield x; } } }... pero esta capa de rendimiento adicional parece una tontería.
¿Hay alguna forma obvia en la que me esté perdiendo para que una función de generador envuelva otra función de generador y aún mantenga la notación * , como una sintaxis de "rendir todo desde"?
Puede usar yield* para producir todos los elementos de otro generador
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"]