import { IEnumerable, IEnumerableFactory, FlatIterable } from '../../types'; function* internalFlatten( src: Iterable, depth: Depth ): Generator> | TSource> { if (depth < 0) { return yield src; } const isIterable = (item: Iterable> | TSource): item is Iterable => Symbol.iterator in Object(item); for (const currentItem of src) { if (isIterable(currentItem)) { yield* internalFlatten(currentItem, depth - 1); } else { yield currentItem; } } } export function applyFlatten( factory: IEnumerableFactory, src: Iterable, depth?: Depth ): IEnumerable, Depth>> { if (Number.isNaN(depth) || (typeof depth === 'number' && depth < 0)) { throw new Error('Invalid depth.'); } function* generator(): Generator, Depth>> { yield* internalFlatten(src, depth ?? 1) as Generator, Depth>>; } return factory.createBasicEnumerable(generator); }