返回

用 Typescript 揭示 Partial、Readonly、Record 和 Pick 的秘密

前端

前言

在 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 类型,但 nameage 属性都是可选项。这意味着我们可以创建一个 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 类型,但 nameage 属性都是只读的。这意味着我们无法修改 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 类型,但只包含 nameage 属性。这意味着我们可以创建一个 PersonNameAndAge 对象,而无需提供 address 属性的值。

总结

Partial、Readonly、Record 和 Pick 是 TypeScript 中非常有用的程序类型工具,它们可以帮助我们轻松地对接口进行二次封装或调整。通过使用这些工具,我们可以创建出满足不同需求的接口,从而提高代码的可维护性和可读性。