Partial
Partial是typescript内置的一个工具类型。 Partial 工具类型作用:它将接受一个泛型(<>尖括号的接口类型), 泛型的所有属性变为可选的。这可以用于创建一个新的类型,创建的类型的属性是原始泛型的子集,并且这些属性都不是必须的。也就是如果有一个对象类型,并且希望该类型的实例只包含部分属性(即,不是所有的属性都是必须提供的),可以使用 Partial 来创建一个新的类型,其中所有的属性都是可选的。
使用场景:
- 表单或配置对象:
-
- 当构建一个表单或者需要处理用户输入时,可能不是所有的字段都需要立即被填写。例如,在一个多步骤的注册流程中,每个步骤可能会填充不同的字段。
- 对于配置对象,有时你并不需要提供所有的选项,而只提供那些你需要改变的选项。
- 更新现有对象:
-
- 如果想更新一个已有对象的部分属性而不影响其他属性,Partial 可以用来定义一个仅包含要更新属性的对象。
- 例如,当从数据库中获取一个用户对象并只想更新用户的电子邮件地址时,可以使用 Partial 来表示更新操作中的用户信息。
- API 请求:
-
- 在某些情况下,API 可能接受部分数据来更新资源,而不是整个资源的数据。此时,Partial 可以用于定义 API 请求的有效载荷类型。
- 函数参数:
-
- 如果函数接收一个对象作为参数,但这个对象不是所有的属性都必须提供,那么可以使用 Partial 来定义参数类型。这样可以让函数更加灵活,因为它可以接受更少数量的属性。
- 默认值设置:
-
- 在初始化对象时,可能想要为某些属性提供默认值。
假设有一个 User 类型:
interface User { id: number; name: string; email: string; }
创建一个类型,使得 User 的所有属性都变成可选
let partialUser: Partial<User> = { email: "user@example.com" };
在这个例子中,partialUser 只提供了 email 属性,id 和 name 是可选的,因此它们可以不存在。
注意事项:
- Partial 会将所有属性变为可选,但它不会改变属性的类型。如果原始类型是必填的(即非 undefined 或 null),那么即使使用 Partial,属性的值也不能是 undefined 或 null,除非原始类型明确允许这些值是 undefined 或 null。
- Partial 适用于对象类型。对于基本类型、联合类型等,它没有效果。
// 定义两个接口满足以上要求
interface Pt1{
name:string;
age:number;
}
interface Pt2{
name?:string;
age?:number;
}
//采用Partial,只需要定义一个接口
interface People {
name:string;
age:number;
}
// 泛型放入接口的类型
let peopleObj:Partial<People>={
name:"jessica",
age:418
}
let people:Partial<People>={
name:"hyo",
}
let people2:Partial<People>={
name:Gloria,
age:16
}
type Partial<T> = { [P in keyof T]?: T[P] | undefined; }这段代码的含义为T这个泛型在使用时就是传入的接口的类型,将来这个类型依然是一个对象。P in keyof T,表示for(key in 对象)的语法,for in循环主要用于遍历普通对象,key是对象的键名,obj[key] 就是对象的键值对的属性值,keyof表示索引查询,可以用于获取某种类型的所有键,其返回类型是联合类型,keyof T就是遍历接口中的键名(属性名)name和age,in用于取联合类型的值,主要用于数组和对象的构造。P相当于一个临时变量用于保存取出的联合类型的值;T[P]表示取出接口中属性的属性值就是string和number。即这段代码最终呈现结果为一个对象:
// 问号表示可选属性
{
name?:string|undefined,
age?:number|undefined
}
Required
Required的用处如以下举例:当接口中的属性有可选参数,但有些情况下需要这个可选参数是必选参数。Required的作用是把泛型的类型(<>尖括号的接口类型)属性设置属性为必选参数。
interface People {
name:string;
age:number;
height?:number
}
// 泛型放入接口的类型
let peopleObj:Required<People>={
// 编译报错
name:"jessica",
age:418
}
type Required<T> = { [P in keyof T]-?: T[P]; }这段代码的含义为T这个泛型在使用时就是传入的接口的类型,将来这个类型依然是一个对象。P in keyof T就是遍历接口中的属性,P相当于一个临时变量用于保存遍历出的接口属性name和age和height;T[P]表示取出接口中属性的属性值就是string和number和number;-?表示抵消去掉问号,有问号就减去问号,没有就不需要减去。即这段代码最终呈现结果为一个对象:
// 问号表示可选属性
{
name:string|undefined,
age:number|undefined,
height:number|undefined,
}