【Typescript进阶】内置工具类型的用法与实现

TypeScript 提供了许多内置的工具类型,这些工具类型可以帮助我们更轻松地定义和操作类

Partial

将一个对象类型的所有属性变为可选。

下面是一个示例,使用 Partial 实现一个可以部分更新用户信息的函数:

interface User {
   
  name: string;
  age: number;
  email: string;
}

const updateUser = (user: User, updates: Partial<User>): User => {
   
  return {
    ...user, ...updates };
}

const user: User = {
    name: 'Alice', age: 30, email: 'alice@example.com' };

const updatedUser = updateUser(user, {
    name: 'Bob' });

在上面的示例中,我们定义了一个 User 接口,它有三个属性:nameageemail。然后我们定义了一个 updateUser 函数,该函数接受一个 User 对象和一个部分用户对象(即,它可以包含 User 对象的部分属性)。该函数返回一个新的 User 对象,其中包含原始 User 对象的所有属性和部分用户对象中的属性。

为了使 updateUser 函数能够接受部分用户对象,我们使用了 Partial<User> 类型。这个类型会将 User 对象中的所有属性变为可选。这意味着我们可以只传递 User 对象中的一部分属性到 updateUser 函数中,而不需要传递所有属性。

下面是一个简单的 TypeScript 实现 Partial 的示例。

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

在这个实现中,我们使用了映射对象类型,它会遍历 T 类型的所有属性,并将它们变为可选属性。由于 ? 符号将属性变为可选,因此我们只需要将属性的类型设置为原始属性的类型即可。

需要注意的是,我们使用 keyof T获取 T 类型的所有属性名称。然后,我们使用 P in keyof T 循环遍历这些属性,并将它们变为可选属性。最后,我们使用 T[P] 获取原始属性的类型,并将其设置为可选属性的类型。

Required

将一个对象类型中的所有属性变为必需的

下面是一个示例,使用 Required 实现一个可以创建必填订单的函数:

interface Order {
   
  id?: number;
  customerId?: number;
  date?: Date;
  amount?: number;
}

const createOrder = (order: Required<Order>): void => {
   
  // ...
}

const order: Order = {
    customerId: 123, amount: 100 };
createOrder(order); // Error: Property 'id' is missing

在上面的示例中,我们定义了一个 Order 接口,它有四个属性:idcustomerIddate amount,其中所有属性都是可选的。然后我们定义了一个 createOrder 函数,该函数接受一个必填订单对象,并在函数内部进行一些操作。

在函数调用中,我们只传递了 Order 对象中的一部分属性,即 customerId amount。由于 Order 对象的其他属性是可选的,因此 TypeScript 编译器会报错,提示缺少 id 属性。

为了将 Order 对象中的所有属性变为必需属性,我们可以使用 Required<Order> 类型。这个类型会将 Order 对象中的所有属性变为必需属性。这意味着我们必须在创建 Order 对象时填写所有属性。

下面是一个简单的 Typescript 实现 Required 的示例:

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

在这个实现中,我们使用了映射对象类型,它会遍历 T 类型的所有属性,并将它们变为必需属性。由于 - 符号将属性变为必需属性,因此我们只需要将属性的类型设置为原始属性的类型即可。

需要注意的是,我们使用 keyof T 获取 T 类型的所有属性名称。然后,我们使用P in keyof T 循环遍历这些属性,并将它们变为必需属性。最后,我们使用 T[P] 获取原始属性的类型,并将其设置为必需属性的类型。

Readonly

将给定类型的所有属性设置为只读。

基本语法如下:

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

其中,T 是要设置为只读的类型。下面是一些使用 Readonly 的示例和它们的实现。

示例 1:将对象的所有属性设置为只读。

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

type ReadonlyPerson = Readonly<Person>;

const person: ReadonlyPerson = {
   
  name: "Alice",
  age: 30,
};

person.name = "Bob"; // Error: Cannot assign to 'name' because it is a read-only property.
person.age = 31; // Error: Cannot assign to 'age' because it is a read-only property.

在上面的示例中,我们使用 Readonly<Person>Person 接口的所有属性设置为只读,并生成了一个 ReadonlyPerson 类型。然后,我们定义了一个包含 ReadonlyPerson 类型的对象 person,并尝试修改它的属性,但是会报错,因为属性是只读的。

示例 2:将对象的部分属性设置为只读。

interface Person {
   
  name: string;
  age: number;
  address: {
   
    city: string;
    street: string;
  };
}

type ReadonlyPerson = {
   
  readonly name: string;
  age: number;
  readonly address: {
   
    readonly city: string;
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jierm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值