条件类型是由条件类型表达式所决定的。

一.条件类型基本使用

可以使用extends关键字和三元表达式,实现条件判断

  1. interface Fish {
  2. name1: string
  3. }
  4. interface Water {
  5. name2: string
  6. }
  7. interface Bird {
  8. name3: string
  9. }
  10. interface Sky {
  11. name4: string
  12. }
  13. type Condition<T> = T extends Fish ? Water : Sky;
  14. let con1: Condition<Fish> = { name2: '水' }

二.条件类型分发

let con2: Condition<Fish|Bird> = { name2: '水' }

这里会用每一项依次进行分发,最终采用联合类型作为结果,等价于:

type c1 = Condition<Fish>;
type c2 = Condition<Bird>;
type c = c1 | c2

三.内置条件类型

  • 1.Exclude排除类型

    type Exclude<T, U> = T extends U ? never : T;
    type MyExclude = Exclude<'1' | '2' | '3', '1' | '2'>
    
  • 2.Extract抽取类型

    type Extract<T, U> = T extends U ? T : never;
    type MyExtract = Extract<'1' | '2' | '3', '1' | '2'>
    
  • 3.NoNullable 非空检测

    type NonNullable<T> = T extends null | undefined ? never : T
    type MyNone = NonNullable<'a' | null | undefined>
    

    四.infer类型推断

  • 1.ReturnType返回值类型

    function getUser(a: number, b: number) {
    return { name: 'zf', age: 10 }
    }
    type ReturnType<T> = T extends (...args: any) => infer R ? R : never
    type MyReturn = ReturnType<typeof getUser>
    
  • 2.Parameters 参数类型

    type Parameters<T> = T extends (...args: infer R) => any ? R : any;
    type MyParams = Parameters<typeof getUser>;
    
  • 3.ConstructorParameters构造函数参数类型

    class Person {
    constructor(name: string, age: number) { }
    }
    type ConstructorParameters<T> = T extends { new(...args: infer R): any } ? R : never
    type MyConstructor = ConstructorParameters<typeof Person>
    
  • 4.InstanceType 实例类型

    type InstanceType<T> = T extends { new(...args: any): infer R } ? R : any
    type MyInstance = InstanceType<typeof Person>
    

    五.infer实践

    将数组类型转化为联合类型

    type ElementOf<T> = T extends Array<infer E> ? E : never;
    type TupleToUnion = ElementOf<[string, number, boolean]>;
    

    将两个函数的参数转化为交叉类型

    type T1 = { name: string };
    type T2 = { age: number };
    type ToIntersection<T> = T extends ([(x: infer U) => any, (x: infer U) => any]) ? U : never;
    type t3 = ToIntersection<[(x:T1)=>any,(x:T2)=>any]>
    

    表示要把T1T2赋予给x,那么x的值就是T1T2的交集。(参数是逆变的可以传父类)
    TS的类型:TS主要是为了代码的安全性来考虑。所以所有的兼容性问题都要从安全性来考虑!