logoProsperBao

Permutation

2022-03-29 08

题目来源(type-challenges)

问题

实现置换类型,将联合类型转换为包含联合置换的数组。

type perm = Permutation<'A' | 'B' | 'C'>; 
// ['A', 'B', 'C'] | ['A', 'C', 'B'] |
// ['B', 'A', 'C'] | ['B', 'C', 'A'] |
// ['C', 'A', 'B'] | ['C', 'B', 'A']

解答

type Permutation<T, K = T> =
  [T] extends [never]
    ? []
    : K extends K
      ? [K, ...Permutation<Exclude<T, K>>]
      : never

拆分

  1. 分解联合类型,获取类型的所有组合
  2. [T] extends [never] 是为了判断传入的泛型是不是为空,如果用 T extends never ? true : false 这样来判断会返回一个 never 类型,并不会返回 true 或者 false,所以利用 [T] 类型来判断是否为空。
  3. K extends K 是判断是否有传入泛型,利用 2 中提到的 T extends never ? true : false 永远会返回 never 的方法判断是否还有传入的类型
  4. 利用 ExcludeT 中 排除掉已经使用过的类型

具体执行

type P = Permutation;
type X = Exclude
执行TK in K extends KX<T, K>[K, ...P<X<T, K>>]结果
1A|B|CAB|C[A, ...P<B|C>]
1.1B|CBC[A, B, ...P<C>]
1.1.1CCnever[A, B, C, ...[][A, B, C
1.2B|CBC[A, B, ...P<C>]
1.2.1CCnever[A, B, C, ...[]][A, C, B]
2A|B|CBA|C[B, ...P<A|C>]
2.1A|CAC[B, A, ...P<C>]
2.1.1CCnever[B, A, C, ...[]][B, A, C]
2.2A|CCA[B, C, ...P<A>]
2.2.1AAnever[B, C, A, ...[]][B, C, A]
3A|B|CCA|B[C, ...P<A|B>]
3.1A|BAB[C, A, ...P<B>]
3.1.1BBnever[C, A, B, ...[]][C, A, B]
3.2A|CBA[C, B, ...P<A>]
3.2.1AAnever[C, B, A, ...[]][C, B, A]