Typescript高级类型-Partial

116 阅读2分钟

Partial定义

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

假设我们有一个定义为User的接口

interface IUser {
    name:string
    age:number
    sex:'male'|'female'
}

使用Partial类型转换后

type PUser=Partial<IUser>
//得到的PUser如下 
type PUser={
    name?:string
    age?:number
    sex?:'male'|'female'
}

那么 Partial<T> 是如何实现类型转化的呢?

  1. 遍历入参 T ,获得每一对 key, value
  2. 将每一对中的 key 变为可选,即添加 ?
  3. 希望得到的是由 key, value 组成的新类型

由Partial的定义我们提出几个疑问:

  • keyof是干什么的?
  • in是干什么的?
  • [P in keyof T]中的中括号是做什么的?
  • ?是可选择类型
  • T[P]是干什么的

keyof

keyof 即索引类型查询操作符 我们可以将 keyof 作用于泛型 T 上来获取泛型 T 上的所有 public 属性名构成的 联合类型

in

我们需要遍历 IUser ,这时候 映射类型就可以用上了,其语法为 [P in Keys]

P:类型变量,依次绑定到每个属性上,对应每个属性名的类型 Keys:字符串字面量构成的联合类型,表示一组属性名(的类型),可以联想到上文 keyof 的作用

T[P]

我们可以通过 keyof 查询索引类型的属性名,那么如何获取属性名对应的属性值类型呢?

这里就用到了 索引访问操作符,与 JavaScript访问属性值的操作类似,访问类型的操作符也是通过 [] 来访问的,即 T[P],其中[]中的 P 与 [P in keyof T] 中的 P 相对应。

最后我们希望得到的是由多个 key, value 组成的新类型,故而在 [P in keyof T]?: T[P]; 外部包上一层大括号。

到此我们解决遇到的所有问题,只需要逐步代入到 Partial 类型定义中即可。 、