likes
comments
collection
share

再也不用担心类型定义冗余了!使用Pick工具类型优化TS开发体验!

作者站长头像
站长
· 阅读数 17

阅读时间约 5 分钟。


在为接口返回的数据编写类型定义时,你肯定遇到过这样的问题:为接口返回的数据定义了一个属性很多的对象类型,而业务中有些逻辑却只需要接口中的某几个字段。像这样的场景,我们需要再单独声明一个类型定义吗?有没有什么好的办法可以将需要的属性提取出来,而不是再重新声明一个新的类型定义呢?

答案是有的。TS 标准库中就有这么一个工具类型:Pick

通过本文的学习,你将彻底学会并掌握 Pick 的用法。同时,我们还会分析它的源码,带你窥见 TS 的高级类型,进而让你写出更加灵活、强大的类型定义。

让我们开始吧~

1. Pick 的作用和用法

Pick 是 TS 标准库中提供的一个工具类型(Utility Type),它用于从一个类型中挑选出一部分属性,然后将挑选出来的属性构造成一个新的类型。

比如我们要从 Person 类型中挑选出其中的 name 属性和 age 属性来构造一个新的类型:

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

type PersonNameAndAge = Pick<Person, "name" | "age">;

PersonNameAndAge 类型等价于下面的类型定义:

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

结合上面的示例我们不难发现,Pick 的第一个参数是要从中挑选属性的原始类型,第二个参数则是一个由第一个参数类型中的键组成的联合类型。

可以看到,新类型 PersonNameAndAge 的属性名和类型都与原始类型 Person 中对应的属性一致。

2. Pick 源码分析

下面是 Pick 的源码定义:

/**
 * From T, pick a set of properties whose keys are in the union K
 */
type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};

源码中涉及到两个关键字 inextends,以及一个操作符 keyof。关键字 in 和 操作符 keyof 在《原来Partial这么神!TS中的对象可选属性解决方案》一文中有细致的讲解,推荐你阅读一下。

extends 是 TS 中的一个关键字,用于表示类型约束,通常情况下用于泛型约束中。在类型参数中使用 extends 可以限制类型参数必须满足某些条件。

keyof T 表示 T 的所有属性名组成的联合类型,比如:

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

type PersonKeys = keyof Person; // "name" | "age"

源码中的关键字 in 则表示迭代联合类型 K 中的每个属性,因此,泛型 P 表示联合类型 K 中的每个元素。这些元素与泛型 T 中的成员属性保持一致。

K extends keyof T 就是限制 K 必须是 keyof T 的子集,也就是 K 中的每个属性都必须是 T 中的属性名之一。K extends keyof T 约束可以确保我们不能选择泛型 T 中不存在的属性名,从而保证了类型的安全性。比如下面的示例:

type PersonName = Pick<Person, "name">; // { name: string; }

// 编译错误:Property 'email' does not exist on type 'Person'
type PersonEmail = Pick<Person, "email">;

由此可见,Pick 的作用就是从一个类型中选出一组数据,进而形成一个新的类型。

3. 总结

TS 标准库为我们提供的 Pick 工具类型,能让我们方便的从一个大型类型中取出需要的属性,从而一定程度上避免冗余的类型定义和类型检查错误。不过,在使用 Pick 时有几点需要注意:

  1. Pick 的第一个参数必须是一个对象类型,并且该类型应是一个拥有成员属性的对象类型。
  2. 确保 Pick 第二个参数是一个联合类型,并且联合类型中的每个成员属性都必须存在于第一个对象类型中。还要保证它不是一个空的联合类型,否则在编译时会报错。

掌握 Pick 能让我们更加熟练的操作 TS 中的类型系统,从而提高代码的可读性和可维护性,能让我们编写出更加灵活的代码,而且还能减少许多重复的类型定义。

你、学废了嘛 ~


本文首发微信公众号码上花甲,欢迎关注。