Skip to content

Instantly share code, notes, and snippets.

@lokshunhung
Last active May 5, 2023 03:53
Show Gist options
  • Select an option

  • Save lokshunhung/d08986dff5923d92b3971b615480d025 to your computer and use it in GitHub Desktop.

Select an option

Save lokshunhung/d08986dff5923d92b3971b615480d025 to your computer and use it in GitHub Desktop.
TS: consume iterable using generator `yield`s
// consumeIterable.ts
type NoInfer<T> = [T][T extends any ? 0 : never]; // https://github.com/millsp/ts-toolbelt/blob/319e551/sources/Function/NoInfer.ts#L27
type AnyIteratorResult = IteratorResult<any, any>;
function consumeIterable<T>(
producer: Iterable<T>,
consumer: () => Generator<undefined, void, NoInfer<T>>
): void {
const produce = producer[Symbol.iterator]();
const consume = consumer();
const exhaustive = arguments[2] ?? true;
let produceResult: AnyIteratorResult = { value: undefined };
let consumeResult: AnyIteratorResult;
// prettier-ignore
while ((
consumeResult = consume.next(produceResult.value),
produceResult = produce.next(),
!consumeResult.done && !produceResult.done
));
switch (true) {
case !consumeResult.done:
throw new Error("[consumeIterable] producer has ended but consumer contains extra `yield` statements");
case !produceResult.done && exhaustive:
throw new Error("[consumeIterable] producer not ended but consumer contains no more `yield` statements");
}
}
consumeIterable.nonExaustive = function consumeIterableNonExhaustive<T>(
producer: Iterable<T>,
consumer: () => Generator<undefined, void, NoInfer<T>>,
): void {
return consumeIterable.call(null, producer, consumer, false);
};
// playground.ts
function expect(_) {
console.log(`expect`, _);
return {
toBe(__) {
console.assert(_ === __, `${_} !== ${__}`);
},
};
}
consumeIterable([1, 2], function* () {
expect(yield).toBe(1);
expect(yield).toBe(2);
// expect(yield).toBe(3);
});
consumeIterable.nonExaustive([1, 2, 3], function* () {
expect(yield).toBe(1);
expect(yield).toBe(2);
// expect(yield).toBe(3);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment