export const forOf = []>(...iterables: T) => new ForOf(iterables); class ForOf[]> { #iterables: T; constructor(iterables: T) { this.#iterables = iterables; } public find(predicate: ForOfPredicate): IterableTupleToUnion | undefined { for (const iterable of this.#iterables) { let index = 0; for (const value of iterable) { const result = predicate(value, index, iterable); if (result) return value; index++; } } } public includes(value: IterableTupleToUnion): boolean { for (const iterable of this.#iterables) { for (const _value of iterable) { if (value === _value) return true; } } return false; } public some(predicate: ForOfPredicate): boolean { for (const iterable of this.#iterables) { let index = 0; for (const value of iterable) { const result = predicate(value, index, iterable); if (result) return true; index++; } } return false; } public every(predicate: ForOfPredicate): boolean { let result = false; for (const iterable of this.#iterables) { let index = 0; for (const value of iterable) { result = predicate(value, index, iterable); index++; } } return result; } public forEach(predicate: ForOfPredicate): void { for (const iterable of this.#iterables) { let index = 0; for (const value of iterable) { predicate(value, index, iterable); index++; } } } public map(predicate: ForOfPredicate): R[] { const arr: R[] = []; for (const iterable of this.#iterables) { let index = 0; for (const value of iterable) { arr.push(predicate(value, index, iterable)); index++; } } return arr; } public reduce(predicate: ForOfReducePredicate, initialValue: R): R { let result: R | undefined = initialValue; for (const iterable of this.#iterables) { let index = 0; for (const value of iterable) { result = predicate(result, value, index, iterable); index++; } } return result; } } type MapKeyValueType = T extends Map ? [K, V] : never; type SetValueType = T extends Set ? V : never; type GeneratorValueType = T extends Generator ? A | B : never; type UnwrapIterableTuple> = { [K in keyof T]: T[K] extends any[] ? T[K][number] : T[K] extends Map ? MapKeyValueType : T[K] extends Set ? SetValueType : T[K] extends Generator ? GeneratorValueType : never } & Record; type IterableTupleToUnion> = UnwrapIterableTuple[number]; type ForOfPredicate[], R> = (value: IterableTupleToUnion, index: number, obj: T[number]) => R; type ForOfReducePredicate[], R> = (acc: R, value: IterableTupleToUnion, index: number, obj: T[number]) => R;