这是我参与更文挑战的第十五天,活动详情查看:更文挑战
通过映射类型
,可以从一个旧的类型,生成一个新的类型,比如
把一个类型/接口中的所有属性变为只读
interface Obj {
a: string;
b: number;
c: boolean;
}
/*
类型推断为
type ReadonlyObj = {
readonly a: string;
readonly b: number;
readonly c: boolean;
}
*/
type ReadonlyObj = Readonly<Obj>;
复制代码
Readonly源码实现原理
/**
* Make all properties in T readonly
*/
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
复制代码
Readonly
是一个可索引类型的泛型接口,
索引签名是 P in keyof T
,
T
是索引类型的查询操作符,表示类型 T 所有属性的联合类型,
P in
相当于执行了一次 for in
操作, 会把变量 P 依次绑定到T
的属性上,
索引签名的返回值 是一个索引访问操作符- T[P]
,代表属性 P 所指定的类型
最后加上 readonly
就把所有属性变成了只读
把一个类型/接口中的所有属性变为可选
interface Obj {
a: string;
b: number;
c: boolean;
}
/*
类型推断为
type PartialObj = {
a?: string | undefined;
b?: number | undefined;
c?: boolean | undefined;
}
*/
type PartialObj = Partial<Obj>;
复制代码
Partial 源码实现原理
/**
* Make all properties in T optional
*/
type Partial<T> = {
[P in keyof T]?: T[P];
};
复制代码
抽取一个类型/接口中的一些子集
interface Obj {
a: string;
b: number;
c: boolean;
}
/*
类型推断为
type PickObj = {
a: string;
b: number;
}
*/
type PickObj = Pick<Obj, "a" | "b">;
复制代码
Pick<T, K extends keyof T> 源码实现原理
/**
* From T, pick a set of properties whose keys are in the union K
*/
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
复制代码
T
代表要抽取的对象
K
有一个约束: 一定是来自T
所有属性字面量的联合类型
新的类型/属性一定要从K
中选取,
总结
以上三种 官方称为 同态, 只会作用于指定的属性(如上面的 Obj),而不会引入新的属性,
创建一些新的属性
interface Obj {
a: string;
b: number;
c: boolean;
}
/*
类型推断为
type RecordObj = {
x: Obj;
y: Obj;
}
*/
type RecordObj = Record<"x" | "y", Obj>;
复制代码
RecordObj
是一个非 同态的类型,
总结
映射类型本质上是一个预先定义的泛型接口,通常还会结合索引类型获取对象的属性和属性值,从而将一个对象映射成我们想要的结构。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END