Generator functions come with prototype
properties that allow for the addition of behavior. The generated generators inherit this behavior. Unfortunately, TypeScript does not seem to recognize this feature, leaving me unsure of how to make it aware.
For instance, let's consider a basic range generator and try to incorporate a map
functionality:
/** Generates integers from 0 up to `hi`, incremented by `step`. */
function* range(hi: number, step: number = 1) {
for (let i = 0; i < hi; i += step) {
yield i;
}
}
range.prototype.map = function*<T>(fn: (arg0: number) => T) {
for (const i of this) {
yield fn(i);
}
};
Unfortunately, this doesn't work as expected. Trying something like range(9).map(i => 9 - i)
triggers an error stating
Property 'map' does not exist on type 'Generator<number, void, unknown>'.
(The code itself functions properly—it's just the TypeScript typing that falters.)
I find myself daydreaming about a potential syntax to define this behavior manually in case TypeScript fails to infer it automatically. Perhaps something along these lines:
interface of range {
map<R>(fn: (i: number) => R): Generator<R>;
}
Is there some secret method I have yet to uncover for achieving this? Or is there any plan to integrate such a feature into the language?