TS之泛型

78 阅读2分钟

泛型

基本使用

使用时才定义类型

推后执行、部分待定的类型

type F<A, B> = A | B  //  返回一个新的类型
type Result = F<string | number> // 

type Intersect<A, B> = A & B
type IntersectResult = Intersect<string, number> // never

extends

extends读作继承包含于

  • 只对泛型有效
    • Tnever,则表达式的值为never
    • T为联合类型,则分开计算
    type LinkString<T> = T extends string ? true : false
    type X1 = LinkString<never> // type X1 = never
    
    type ToArray<T> = T extends unknown ? T[] : never
    type Result = ToArray<string | number>
    // 相当于 type Result = string | number
    

keyof

  • keyof获取类型中的key的集合
    type Person = { name: string; age: string }
    type GetKeys<T> = keyof T
    type X = GetKeys<Person> // type X = 'name' | 'age '
    

类型约束

  • 获取类型中key的类型
    type Person = { name: string; age: string };
    type  GetKeyType<T, K extends keyof T> = T[K]
    

in

  • 映射类型
  • 使用 in 约束key
    type T<T> = {
        [K in string]: T[K] 
    }    
    

去掉readonly

  • readonly 变为可写的
  • 使用 -readonly
    type Person = {
      readonly id: number;
      readonly name: string;
      readonly age: number;
    };
    type Mutable<T> = {
        -readonly [K keyof T]: T[K]
    }
    

实现以下类型

  1. Readonly
    • 所有属性变为 readonly
    type Person = { id?: number; name: string; age: number };
    type Readonly<T> = {
       readonly [K in keyof T]: T[K] 
    }
    
  2. Partial
    • 所有属性变为可选
    type Person = { id?: number; name: string; age: number };
    type Partial<T> = {
        [K in Keyof T]?: T[K]
    }
    
  3. Required
    • 所有属性变为必选
    • 使用 -?
type Person = { id?: number; name: string; age: number };
type Required<T> = {
    [K in keyof T]-?: T[K] 
}
  1. Record
    type Record<T extends string|number|symbol, V> = {
        [K: T]: V
    }
    
  2. Exclude
    • 排除类型中相同的
    type Exclude<T, K> = T extends K ? never : T 
    type E1 = Exclude< 1|2|3, 1|2 > // 3
    
  3. Extract
    • 取类型中的交集、
    type Extract<T, K> = T extends K ? T : never
    type E1 = Extract< 1|2|3, 2|4 > // 2
    
  4. Pick
    • 取类型中传入的属性
    type Person = { id?: number; name: string; age: number };
    type Pick1<T, K extends keyof T> = {
      [K2 in K]: T[K2];
    };
    type P1 = Pick1<Person, "age">;
    
  5. Omit
    • 排除传入的类型
      1. 方式一
        • 通过 as 断言类型,Key extends K ? never : Key为Key包含于K则取never,否则取Key
        type Person = { id?: number; name: string; age: number };
        type Omit<T, K> = {
            [Key in keyof K as Key extends K ? never : Key]: T[Key]
        }
        
      2. 方式二
        • 使用 Exclude排除传入的key,在通过Pick获取剩下的key的类型
        type Person = { id?: number; name: string; age: number };
        type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;