hardfist/stackoverflow

conditional type

hardfist opened this issue · 1 comments

哈哈哈很复杂,来讨论讨论吧

本文主要是对于规范的解释,和对各种edge case的说明
先讲 conditional type, conditional type主要用来表述一些non-uniform type mapping,
conditional type 可以根据判断条件进行mapping。
conditional type定义如下

T extends U ? X : Y

为了方便后续讨论,各个参数定义如下
T: checkedType
U: extendsType
X: trueType
Y: falseType
上述type的意思是: 如果T能assignable(不是subtype)给U那么结果是X,否则结果是Y,
如果上述表达式里的T和U含有泛型参数,那么condition type的结果就被defer了,否则该表达式的结果就根据T extends U的结果被resolve为X或者Y。
举例如下

type TypeName<T> =
    T extends string ? "string" :
    T extends number ? "number" :
    T extends boolean ? "boolean" :
    T extends undefined ? "undefined" :
    T extends Function ? "function" :
    "object";

type T0 = TypeName<string>;  // "string"
type T1 = TypeName<"a">;  // "string"
type T2 = TypeName<true>;  // "boolean"
type T3 = TypeName<() => void>;  // "function"
type T4 = TypeName<string[]>;  // "object"

distributive conditional types

当checkedType是naked type parameter时,condition types 就变为distributive conditional types

这里只有两层意义

  • 只有checkedType会被当做distributive conditional type
  • 只有当checkedType为naked type时,才会被当做 distributive conditional types
type Fun<T> = T extends U ? X : Y
当T = A|B|C时
type a = Fun<A|B|C> = (A extends U ? X:Y)|(B extends X : Y) | (C extends U ? X : Y)

当我们实例化distributive conditional typeT extends U ? X : Y时,
如果T是Union type,那么实例化时T就被resolve为各个成员结果的合并。

这里又牵扯到啥时uniontype

  • union type

  • naked type parameter

type res = Fun<string|number> extends ((k: infer I) => void) ? I : never;



type res2 = B<Fun<string|number>>


type Fun<U> = U extends any ? (k:U) => void : never;


type B<T> = [T]  extends [((k: infer I) => void)] ? I : never;

  • contravariant => intersection
  • distributive conditional type
  • union type 判定: boolean | any |
  • type resolve && type check
  • lhs && rhs