/ src / helpers / mapFilter.ts
mapFilter.ts
 1  type GuardType<T, P> = P extends (value: any, ...args: any[]) => value is infer U ? U : T;
 2  
 3  export const mapFilter = <
 4  	T,
 5  	M extends (item: T, index: number) => unknown,
 6  	F extends (item: ReturnType<M>, index: number) => boolean,
 7  >(
 8  	arr: Iterable<T>,
 9  	map: M,
10  	filter: F,
11  ) => Array.from(mapFilterIterator(arr, map, filter));
12  
13  function* mapFilterIterator<
14  	T,
15  	M extends (item: T, index: number) => unknown,
16  	F extends (item: ReturnType<M>, index: number) => boolean,
17  >(arr: Iterable<T>, map: M, filter: F): Iterable<GuardType<ReturnType<M>, F>> {
18  	let i = 0;
19  
20  	for (const item of arr) {
21  		const v = map(item, i) as ReturnType<M>;
22  		if (filter(v, i)) {
23  			yield v as GuardType<ReturnType<M>, F>;
24  		}
25  		i += 1;
26  	}
27  }