Last active
July 10, 2023 00:24
-
-
Save cefn/6a1153006cf3d99970321387d11776fa to your computer and use it in GitHub Desktop.
Mapping a generator by decorated yielded values.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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