Skip to content

Instantly share code, notes, and snippets.

@cefn
Last active July 10, 2023 00:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cefn/6a1153006cf3d99970321387d11776fa to your computer and use it in GitHub Desktop.
Save cefn/6a1153006cf3d99970321387d11776fa to your computer and use it in GitHub Desktop.
Mapping a generator by decorated yielded values.
export function decorateSequence<
G extends Generator<Yielded>,
Yielded,
Decorated
>(
generator: G,
decorate: (yielded: Yielded) => Decorated
): Generator<Decorated, GReturned<G>, GNexted<G>> {
function mapResult(
result: IteratorResult<Yielded, GReturned<G>>
): IteratorResult<Decorated, GReturned<G>> {
const decoratedResult: IteratorResult<
Decorated,
GReturned<G>
> = result.done === true
? result
: {
done: result.done,
value: decorate(result.value),
};
return decoratedResult;
}
return {
[Symbol.iterator]() {
return this;
},
next(...args) {
return mapResult(generator.next(...args));
},
return(value) {
return mapResult(generator.return(value));
},
throw(e) {
return mapResult(generator.throw(e));
},
};
}
/** Infers the yielded value from a generator type */
export type GYielded<G extends Generator> = G extends Generator<infer yielded>
? yielded
: never;
/** Infers the next() argument from a generator type */
export type GReturned<G extends Generator> = G extends Generator<
any,
infer returned
>
? returned
: never;
/** Infers the returned value from a generator type */
export type GNexted<G extends Generator> = G extends Generator<
any,
any,
infer nexted
>
? nexted
: never;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment