Partial<T>:快速把某个接口类型中定义的属性变成可选
Partial
是 TS 中的一个工具类型(Utility Type),它的作用只有一个:将一个对象类型中的所有属性变为可选属性。换句话说,Partial<T>
接受一个泛型参数 T
,并返回一个新的类型,新类型与 T 相同,但是 T
类型中的所有属性都变为可选属性。
type User = {
id: number;
name: string;
age: number;
}
type UpdatedPerson = Partial<User>;
得到的 UpdatedPerson
类型与下面的类型定义是相同的:
type UpdatedPerson = {
id?: number;
name?: string;
age?: number;
}
参考:TS 关于泛类约束partial<T>_ts partial_moannian的博客-CSDN博客
原来Partial这么神!TS中的对象可选属性解决方案_ts中的partial_滕青山ᅠ的博客-CSDN博客
// Partial 源码分析
/**
* Make all properties in T optional
*/
type Partial<T> = {
[P in keyof T]?: T[P];
};
这段源码使用关键字 in
和操作符 keyof
定义了一个映射类型。
keyof
是 TS 中的索引类型查询操作符,用于获取一个对象类型的所有属性名称的联合类型。
interface User {
name: string;
age: number;
gender: string;
}
type UnionType = keyof User;
User 是一个对象类型,keyof
会获取 User
对象类型的属性名称联合类型,也就是 "name" | "age" | "gender"
。UnionType 的类型与下面的类型定义是等价的:
type UnionType = "name" | "age" | "gender";
要注意的是,keyof
操作符只能用于对象类型。除对象类型外的其他类型,keyof
是无法使用的。例如:
type MyNumber = number;
type MyNumberKey = keyof MyNumber; // 编译错误:Type 'number' has no matching index signature for type 'keyof number'
- 再来看源码中的
in
关键字,这个关键字的作用是用于映射类型的。在这里in
表示的是迭代联合类型中的每个属性,而泛型P
就表示这些属性。
这样,Partial
类型中的成员就与传入的泛型 T
中的成员一致了。属性名称后的 ?
表示可选类型,属性值则是取的泛型 T
中的属性值。由此,便将泛型 T
中的属性转变成了可选属性。
Required<T>:把所有可选属性变成必选属性
interface Person {
name: string;
age: number;
sex?: string;
}
/**
* type PersonOptions = {
* name: string;
* age: number;
* sex: string;
* }
*/
type PersonRequired = Required<Person>;
// 实现原理
type Required<T> = {
[P in keyof T]-?: T[P] // `-?` 符号是一个操作符,用于将属性变为必需的,即必须存在并且不能为 undefined 或 null。
}
Readonly<T>:把所有属性变成只读属性
// 实现原理
/**
* Make all properties in T readonly
*/
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};