开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情
映射类型
- 当你不想重复定义类型,一个类型可以以另一个类型为基础创建新类型,通俗的话就是,以一个类型为基础,根据它推断出新的类型
- Readonly / Partial 关键字
- Record / Pick 映射关系
- Readonly Partial 和 Pick 是同态的,但 Record 不是,因为Record并不需要输入类型来拷贝属性,所以它不属于同态
readonly 只读映射
定义一个IPerson接口,然后定义一个MyReadonly类型,接收一个类型,最终类型是这个接收的类型的所有属性都是readonly的属性;
interface IPerson {
name: string;
age: number;
}
// {
// readonly name: string;
// readonly age: number;
// }
type MyReadonly<T> = {
readonly [P in keyof T]: T[P]
}
type res = MyReadonly<IPerson>
Partial可选映射
同readonly一样,直接将 源类型映射成所有属性为可选的类型。
type MyPartial<T> = {
[P in keyof T]?: T[P];
}
type res=MyPartial<IPerson>
可以通过 + - 添加或者删除
这个例子直接把readonly 和 可选干掉了
interface IPerson {
readonly name?: string;
readonly age?: number;
}
type Test<T> = {
-readonly [K in keyof T]-?: T[K];
}
type res = Test<IPerson>
内置的Readonly / Partial
interface IPerson3 {
name: string;
age: number;
}
type res1 = Readonly<IPerson3>
type res2 = Partial<IPerson3>
Record 指作为一个单位来处理的一组相连的数据 映射类型
将第一个联合类型所有可能的类型都作为新类型的属性,属性值的类型为第二个参数的类型. 想要做为属性的就写在前面,想要做为值的类型写在后面
type Name = "person" | "animal"
type Person = {
name: string;
age: number;
}
type Type1 = Record<Name, Person>
type MyRecord<T extends string | number | symbol, U> = {
[P in T]: U;
}
Pick 将原有类型中的部分类型映射到新类型中
想要映射哪个属性,第二个类型就包含哪个属性
interface IInfo {
name: string;
age: number;
}
// 源码
type MyPick<T, P extends keyof T> = {
[K in P]: T[K];
}
type Type1 = Pick<IInfo, 'name'>
Record不属于同态,我个人理解,是因为它不需要一个具体的复杂类型就可以生成一个类型,也就是可以通过string,number等基础类型生成{x:string:number}类型
interface IInfo {
name: string;
age: number;
}
type MyRecord<T extends string | number | symbol, U> = {
[P in T]: U;
}
type res = Record<string, number>