Typescript 全解学习(3)泛型

107 阅读2分钟

1. 对泛型有什么了解?

  1. 泛型就是引入类型变量来满足类型不确定的需求。
  2. TS中的泛型就类似于JS中的函数。
  3. JS中提供了Number,String,Array,Function,Object等构造函数。 TS中提供了Readonly,Partial,Required,Exclude,Extract,Pick,Omit,等泛型

泛型实现细节:

  1. 泛型约束:使用extends关键字 as关键字
  2. 获取对象的Key:使用in keyof关键字
  3. 泛型中的只读readonly 非只读 -readonly
  4. 泛型中的可选? 非可选 -?
  5. 泛型中定义类型变量 infer XX
  6. 泛型中的操作类比 乘法分配率 (A+B)C=AC+BC 乘法中的零 0C=0 联合类型 type ToArray=T extends unknown ? T[]:never type Result=ToArray<string|number> // 泛型中的联合类型操作要分开进行操作,然后再合并到一起 // Result的类型:正确答案:string[]|number[] 错误答案:(string|number)[]

type ResultNever=ToArray // 泛型中,输入是never,输出一定是never // ResultNever的类型:never 错误答案:never[]

2.了解哪些泛型API?

1. Readonly 只读

readonly 的实现很简单,就是在原先的对象的key前面加readonly 关键字.同理,非只读就是把readonly改为-readonly就可以了

interface Todo {
    title: string
    description: string
  }
type MyReadonly<T>={readonly [K in  keyof T]:T[K]} 
  const todo: MyReadonly<Todo> = {
    title: "Hey",
    description: "foobar"
  }
  
  todo.title = "Hello" // Error: cannot reassign a readonly property
  todo.description = "barFoo" // Error: cannot reassign a readonly property

2. Partial 可选

type Partial<T>={[Key in keyof T]?:T[Key] }

3. Required 必填

type Required<T>={[Key in keyof T]-?:T[Key] }

4. pick 是指从原对象T中,选出key为K的子集组成的数组

type MyPick<T ,K extends keyof T>={ [Key in K ] : T[Key] }

5.MyParameters 如何获取一个函数的参数类型?

type MyParameters<F extends (...args:any[])=>any>= F extends (...args:infer X)=>any ? X: never

3.数组类型体操

// infer 关键字 显式的声明一个泛型变量. 代表这是一个推断的类型,后边可以取任意名字
数组模式匹配
[...infer Rest, infer Last]
数组有length属性
type A=['a','b','c']
type B=A[length] // TS 元组也自带length属性
// 元组扩展
type A=['a','b','c']
type B=[...A,'last']
type C=[1,2,3]
type D=[...B,...C]
//如何获取数组最后一个元素类型
type Last<T extends unknown[]>=T extends [...unknown[], infer L]?L:never
// infer L 就相当于我自己定义了一个类型变量,然后自己使用
type E=Last<D> // 3

4.字符串类型体操

type A = 'fang'
type B = Capitalize<A>  // 首字母大写
type C= Uncapitalize<A> // 首字母小写
type D = Lowercase<A>  // 全部小写
type E = Uppercase<A>  // 全部大写
type F = `${A}${B}` // 模版字符串
type First<T extends string>= T extends `${infer F}${string}`?F:never 
// 获取字符串第一个。 字符串做匹配,会默认前面的只匹配一个字符
type Rust = First<A>
// 字符串转联合类型去重
type StringToUnion<S extends string>=S extends `${infer First}${infer Rest}`? First|StringToUnion<Rest>:never
type ResultUnion =StringToUnion<"xxdnihaoya"> // 联合类型会自动去重
// 字符串转元组
type StringToTuple<S extends string>=S extends `${infer First}${infer Rest}`? [First,...StringToTuple<Rest>]:[]
type Resulttuple=StringToTuple<'xxdnihaoya'>