type-challenges:Without

15 阅读1分钟

Without

问题描述

实现一个像 Lodash.without 函数一样的泛型 Without<T, U>,它接收数组类型的 T 和数字或数组类型的 U 为参数,会返回一个去除 U 中元素的数组 T。

例如:

type Res = Without<[1, 2], 1>; // expected to be [2]
type Res1 = Without<[1, 2, 4, 1, 5], [1, 2]>; // expected to be [4, 5]
type Res2 = Without<[2, 3, 2, 3, 2, 3, 2, 3], [2, 3]>; // expected to be []
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'type cases = [
  Expect<Equal<Without<[1, 2], 1>, [2]>>,
  Expect<Equal<Without<[1, 2, 4, 1, 5], [1, 2]>, [4, 5]>>,
  Expect<Equal<Without<[2, 3, 2, 3, 2, 3, 2, 3], [2, 3]>, []>>,
]
​
​
// ============= Your Code Here =============
// 答案
type ToUnion<T> = T extends any[] ? T[number] : T
type Without<T extends any[], U extends number|number[]> = 
  T extends [infer R, ...infer F]
    ? R extends ToUnion<U>
      ? Without<F, U>
      : [R, ...Without<F, U>]
  : T
    
    

U 转为联合类型是关键解题思路,之后会触发分布式条件类型进行判断,每一个 Without<F, U> 最后都会走到结果 [R, ...Without<F, U>],所以这里使用 ...Without<F, U> 将所有的结果放在一个数组中返回。