semlinker/awesome-typescript

「重学TS 2.0 」TS 练习题第二十五题

semlinker opened this issue · 9 comments

实现一个 IsUnion 工具类型,判断指定的类型是否为联合类型。具体的使用示例如下所示:

type IsUnion<T, U = T> = // 你的实现代码

type I0 = IsUnion<string|number> // true
type I1 = IsUnion<string|never> // false
type I2 =IsUnion<string|unknown> // false

请在下面评论你的答案。

suica commented
type IsUnion<T, U = T> = T extends U? ([T,U] extends [U,T] ?  false: true) : never;
type IsUnion<T, U = T> = T extends U ? ([U] extends [T] ? false : true) : never;

type I0 = IsUnion<string | number>; // true
type I1 = IsUnion<string | never>; // false
type I2 = IsUnion<string | unknown>; // false
type IsUnion<T, U = T> = IsEqual<UnionToIntersection<U>, T> extends true
  ? false
  : true;

type IsEqual<T, U> = (<G>() => G extends T ? 1 : 2) extends <G>() => G extends U
  ? 1
  : 2
  ? true
  : false;

type UnionToIntersection<U> = (U extends any
? (k: U) => void
: never) extends (k: infer I) => void
  ? I
  : never;

type I0 = IsUnion<string | number>; // true
type I1 = IsUnion<string | never>; // false
type I2 = IsUnion<string | unknown>; // false
type IsUnion<T, U = T> = T extends U ? ([U] extends [T] ? false : true) : never;

type I0 = IsUnion<string | number>; // true
type I1 = IsUnion<string | never>; // false
type I2 = IsUnion<string | unknown>; // false
type IsUnion<T, U = T> = T extends U ? ([U] extends [T] ? false : true) : never;

[U] extends [T] 这里不是很懂,老铁能解释下吗

 type IsUnion<T> = ((T extends any ? ((arg: T)=> void) : never) extends ((arg: infer R)=> void) ? R : never) extends never ? true : false
    type I0 = IsUnion<string|number> // true
    type I1 = IsUnion<string|never> // false
    type I2 = IsUnion<string|unknown> // false
    type I3 = IsUnion<'string'|'unknown'> // false
// 实现一个 IsUnion 工具类型,判断指定的类型是否为联合类型。具体的使用示例如下所示:

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

type I0 = IsUnion<string|number> // true
type I1 = IsUnion<string|never> // false
type I2 =IsUnion<string|unknown> // false
type I3 =IsUnion<string> // false

知识点:

  1. 联合类型作为泛型的时候 extends 会触发分发执行
  2. 联合类型T 写成 [T] 就变成了普通类型,extends的时候不会分发执行

这里第一步的 T extends any 肯定为真,这个其实就是利用其分发的特性,后面的 [T] 就是一个联合类型拆开后的某一个,因此如果是联合类型的话 [U] extends [T] 一定为否

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

type I0 = IsUnion<string | number> // true
type I1 = IsUnion<string | never> // false
type I2 = IsUnion<string | unknown> // false

利用联合类型的参数在extends左侧时,会有联合分散的处理,分开后,每个具体类型再通过[]包裹,防止分散,进而判断是否🤮tends

type I0 = IsUnion<string|number> // true
type I1 = IsUnion<string|never> // false
type I2 =IsUnion<string|unknown> // false


type IsUnion<T, U = T> = 
  T extends any
    ? [U] extends [T]
      ? false
      : true
    : false
//question
// 实现一个 IsUnion 工具类型,判断指定的类型是否为联合类型。具体的使用示例如下所示:
// type IsUnion<T, U = T> = // 你的实现代码
// type I0 = IsUnion<string|number> // true
// type I1 = IsUnion<string|never> // false
// type I2 =IsUnion<string|unknown> // false


//answer
type UnionToIntersection1<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never
type IsUnion<T, U = T> = U extends UnionToIntersection1<T> ? false : true
type I0 = IsUnion<string | number> // true
type I1 = IsUnion<string | never> // false
type I2 = IsUnion<string | unknown> // false