共计 字 • 阅读约 min

利用分布条件类型解 Type-challenges IsUnion

IsUnion

题目

type case1 = IsUnion<string>  // false
type case2 = IsUnion<string | number>  // true
type case3 = IsUnion<[string | number]>  // false

题解

type IsUnion<T, U = T> = 
  T extends U 
  ? [U] extends [T] 
    ? false 
    : true 
  : never

疑惑?

做了半天没做出来,忍不住去看了题解,于是就看到 [T][U] 。我就纳闷了,[T][U] 有什么区别?为什么就可以区分出联合类型

题解原理

问题的关键就在于利用分布条件类型,extends 会应用于联合类型的每个成员

什么是分布条件类型?

  • 被检查类型(即上述的 T)是裸类型参数 的条件类型称分布条件类型
  • 在实例化期间,分布条件类型 会自动分布在联合类型上,即条件类型应用于联合类型的每个成员,结果是所有结果的联合。

什么是裸类型参数?

类型参数没有被包装到另一种类型中,例如:数组、元组、函数、或任意其他泛型类型。

原理

例子 1:IsUnion<string|number>

  1. T extends O 发生了什么

我们以为:string | number extends string | number
实际上是:(string extends string | number) | (number extends string |number)

type IsUnion1<T, U = T> = 
  T extends U 
    ? [T] 
    : never
  
type testT = IsUnion1<string|number>  // [string] | [number]

type IsUnion2<T, U = T> = 
  T extends U 
    ? [U] 
    : never

type testU = IsUnion2<string|number>  // [string | number]

  1. 可以看到此时 [T] 已经变成了 [string] | [number],但是 [O] 由于没有被分布条件类型分布 [string | number] ,这个时候比较 [U][T] 是不成立的,说明是联合类型

例子 2:isUnion

利用分布条件类型,T 也只有一种类型,此时 [T][string][O][string],该情况下 extends 成立,返回 false。

部分内容摘自 link



文章更新于: 2022-4-27 16:26:11