用 Typescript 揭示 Partial、Readonly、Record 和 Pick 的秘密
2023-11-04 13:15:48
前言
在 TypeScript 中,接口是一种非常重要的类型定义工具,它允许我们为对象定义一套属性和方法的规范。接口可以用来约束对象的数据类型,并确保对象具有预期的行为。
然而,在实际开发中,我们经常需要对接口进行二次封装或调整,以满足不同的需求。例如,我们可能需要创建一个只读的接口,或者创建一个仅包含部分属性的接口。为了方便开发者进行此类操作,TypeScript 在 2.1 版本中加入了一些程序类型工具,包括 Partial、Readonly、Record 和 Pick。
Partial
Partial 类型用于创建一个新的类型,该类型包含原有类型的所有属性,但这些属性都是可选项。换句话说,Partial 类型允许我们创建不包含任何必需属性的对象。
interface Person {
name: string;
age: number;
}
type PartialPerson = Partial<Person>;
const person: PartialPerson = {
name: "John"
};
在上面的例子中,PartialPerson
类型继承自 Person
类型,但 name
和 age
属性都是可选项。这意味着我们可以创建一个 PartialPerson
对象,而无需提供 age
属性的值。
Readonly
Readonly 类型用于创建一个新的类型,该类型包含原有类型的所有属性,但这些属性都是只读的。换句话说,Readonly 类型不允许我们修改对象中的属性。
interface Person {
name: string;
age: number;
}
type ReadonlyPerson = Readonly<Person>;
const person: ReadonlyPerson = {
name: "John",
age: 30
};
person.name = "Mary"; // Error: Cannot assign to 'name' because it is read-only
在上面的例子中,ReadonlyPerson
类型继承自 Person
类型,但 name
和 age
属性都是只读的。这意味着我们无法修改 person
对象中的属性,否则会引发错误。
Record
Record 类型用于创建一个新的类型,该类型表示一个键值对集合。换句话说,Record 类型允许我们创建一个对象,其键名和键值都是指定类型的。
type PersonRecord = Record<string, Person>;
const personRecord: PersonRecord = {
"john": {
name: "John",
age: 30
},
"mary": {
name: "Mary",
age: 25
}
};
在上面的例子中,PersonRecord
类型表示一个键值对集合,其中键名是字符串类型,键值是 Person
类型。这意味着我们可以创建一个 PersonRecord
对象,其中键名是人的姓名,键值是人的个人信息。
Pick
Pick 类型用于创建一个新的类型,该类型包含原有类型的一部分属性。换句话说,Pick 类型允许我们从原有类型中选择所需的属性,并创建一个新的类型只包含这些属性。
interface Person {
name: string;
age: number;
address: string;
}
type PersonNameAndAge = Pick<Person, "name", "age">;
const person: PersonNameAndAge = {
name: "John",
age: 30
};
在上面的例子中,PersonNameAndAge
类型继承自 Person
类型,但只包含 name
和 age
属性。这意味着我们可以创建一个 PersonNameAndAge
对象,而无需提供 address
属性的值。
总结
Partial、Readonly、Record 和 Pick 是 TypeScript 中非常有用的程序类型工具,它们可以帮助我们轻松地对接口进行二次封装或调整。通过使用这些工具,我们可以创建出满足不同需求的接口,从而提高代码的可维护性和可读性。