返回

TypeScript类型体操的奇妙世界:第三章探索更复杂的类型构造

前端

TypeScript类型体操训练(三)

在前面两章中,我们已经实现了PickExclude,并且学习了inkeyofextends等的用法。本章我们将这些知识结合起来,实现更为复杂的类型,然后再探寻新的解决方式。

实现Partial类型

Partial<T>用于将T类型的每个属性变成可选属性。例如:

interface Person {
  name: string;
  age: number;
}

type PartialPerson = Partial<Person>;

const person: PartialPerson = {
  name: 'John'
};

此时,person对象的age属性是可选的,可以不赋值。

我们来实现Partial类型:

type Partial<T> = {
  [P in keyof T]?: T[P];
};

使用in关键字遍历T类型的键,然后使用?将每个属性变成可选属性。

实现Required类型

Required<T>用于将T类型的每个属性变成必填属性。例如:

interface Person {
  name: string;
  age?: number;
}

type RequiredPerson = Required<Person>;

const person: RequiredPerson = {
  name: 'John',
  age: 30
};

此时,person对象的age属性是必填的,必须赋值。

我们来实现Required类型:

type Required<T> = {
  [P in keyof T]-?: T[P];
};

使用in关键字遍历T类型的键,然后使用-将每个属性变成必填属性。

实现Readonly类型

Readonly<T>用于将T类型的每个属性变成只读属性。例如:

interface Person {
  name: string;
  age: number;
}

type ReadonlyPerson = Readonly<Person>;

const person: ReadonlyPerson = {
  name: 'John',
  age: 30
};

person.name = 'Mary'; // 报错:无法给只读属性赋值

此时,person对象的nameage属性都是只读的,不能重新赋值。

我们来实现Readonly类型:

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

使用in关键字遍历T类型的键,然后使用readonly将每个属性变成只读属性。

实现Record类型

Record<K, V>用于创建具有指定键类型K和值类型V的对象类型。例如:

type PersonRecord = Record<string, Person>;

const personRecord: PersonRecord = {
  'john': {
    name: 'John',
    age: 30
  },
  'mary': {
    name: 'Mary',
    age: 25
  }
};

此时,personRecord对象是一个键类型为字符串,值类型为Person对象的映射。

我们来实现Record类型:

type Record<K, V> = {
  [key: K]: V;
};

使用key作为键,然后使用V作为值类型,创建对象类型。

结语

本章我们学习了如何实现PartialRequiredReadonlyRecord等类型。这些类型在实际开发中非常有用,可以帮助我们编写出更健壮的代码。