Intersection

39 阅读1分钟
Implement the type version of Lodash.intersection with a little difference. Intersection takes an Array T containing several arrays or any type element including the union type, and returns a new union containing all intersection elements.
type Res = Intersection<[[1, 2], [2, 3], [2, 2]]>; // expected to be 2
type Res1 = Intersection<[[1, 2, 3], [2, 3, 4], [2, 2, 3]]>; // expected to be 2 | 3
type Res2 = Intersection<[[1, 2], [3, 4], [5, 6]]>; // expected to be never
 */
type IsBelongTo<T, U, R = false> = U extends [infer F, ...infer Rest] ? F extends any[] ? T extends ArrToUinon<F> ? IsBelongTo<T, Rest, true> : false : T extends F ?  IsBelongTo<T, Rest, true> : false : R
type GetBelongEle<T, U> = T extends infer K ? K extends ArrToUinon<U>  ? K :never: never
type FArrIntersection<T, U> = T extends [infer F, ...infer Rest] ? IsBelongTo<F, U> extends true ? [F, ...FArrIntersection<Rest,U>] : [...FArrIntersection<Rest,U>]:[]
type FEleIntersection<T, U, R = never> = U extends [infer F, ...infer Rest] ? FEleIntersection<GetBelongEle<T,F>, Rest,GetBelongEle<T,F>> : R
type ArrToUinon2<T> = T extends [infer F, ...infer Rest] ? F | ArrToUinon2<Rest>: never
type Intersection<T> =  T extends [infer F, ...infer Rest] ? F extends any[] ? ArrToUinon2<FArrIntersection<F, Rest>> :FEleIntersection<F, Rest> : never
type Re5 = Intersection<[[1, 2],[2, 3], [2, 2]]>;
type Re6 = Intersection<[[1, 2, 3], [2, 3, 4], [2, 2, 3]]>;
type Re7 = Intersection<[[1, 2], [3, 4], [5, 6]]>