# 十三.映射类型

前言

根据旧的类型创建出新的类型, 我们称之为映射类型

# 1.Partial

将定义的类型属性转化为可选属性

# 1.1 案例

interface PersonType {
  name: string;
  age: string;
  phone: string;
}
// type PartialPersonType = Partial<Person>;
// {
//   name?: string;
//   age?: string;
//   phone?: string;
// }

const person: PersonType = {
    name:'xiaoming',
    age:'14',
    phone:'18232323232323'
}

const student:Partial<PersonType> = {
    name:'xiaoming',
    age:'14',
}

const body:Partial<PersonType> = {
    name:'xiaoming',
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 1.2 实现原理

遍历所有的属性将属性设置为可选属性,但是无法实现深度转化

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

实现深度转化,如果值时对象继续深度转化

type DeepPartial<T> = {
  [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};
type DeepPartialPerson = DeepPartial<Person>;
1
2
3
4

# 2.Required

将定义的类型属性转化为必填属性

# 2.1 案例

interface PersonType {
  name: string;
  age?: string;
  phone?: string;
}
// type RequiredPersonType = Required<Person>;
// {
//   name: string;
//   age: string;
//   phone: string;
// }

const student:PersonType = {
    name:'xiaoming',
    age:'14',
}

const body:PersonType = {
    name:'xiaoming',
}

const person: Required<PersonType> = {
    name:'xiaoming',
    age:'14',
    phone:'18232323232323'
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 2.2 实现原理

遍历所有的属性将所有的属性转化为必填属性

type Required<T> = { [K in keyof T]-?: T[K] };
1

实现深度转化,如果值时对象继续深度转化

type DeepRequired<T> = {
  [K in keyof T]-?: T[K] extends object ? DeepRequired<T[K]> : T[K];
};
1
2
3

# 3.Readonly

对已定义的类型中转化仅读属性

type Readonly<T> = { readonly [K in keyof T]: T[K] };
type RequiredPerson = Readonly<Person>;
1
2

将所有属性变为仅读属性

# 4.Pick

对已定义的类型中挑选所需的属性

type Pick<T, U extends keyof T> = { [P in U]: T[P] };
type PickPerson = Pick<Person, "name" | "age">;
1
2

在已有类型中挑选所需属性

# 5.Record

对已定义的类型中记录类型

type Record<K extends keyof any, T> = { [P in K]: T };
let person: Record<string, any> = { name: "abc", age: 11 };
1
2

实现 map 方法,我们经常用 record 类型表示映射类型

function map<T extends keyof any,K,U>(obj,Record<T,K>,callback:(item:K,key:T)=>U){
  let result = {} as Record<T,U>
  for(let key in obj){
    result[key] = callback(obj[key],key)
  }
  return result
}
const r = map({name:'abc',age:11},(item,key)=>{
  return item
})
1
2
3
4
5
6
7
8
9
10

# 6.Omit

对已定义的类型中忽略某些属性

let person = {
  name:'abc',
  age:111
  addrsss:'ddddd'
}
type Omit<T,K extends keyof T> = Pick<T,Exclude<keyof T,K>>
type OmitAddress = Omit<typeof person,'address'>
1
2
3
4
5
6
7

忽略 person 中的 addresss 属性(先排除掉不需要的 key,再通过 key 选出需要的属性)