前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >TypeScript 类型体操:提取对象指定 key 并设置为必填

TypeScript 类型体操:提取对象指定 key 并设置为必填

作者头像
前端西瓜哥
发布2022-12-21 19:55:30
发布2022-12-21 19:55:30
3.2K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,我是前端西瓜哥。今天我们来做一道 TypeScript 类型编程题。

我们需要实现一个 RequiredPick 类,从一个对象类型中提取指定的 key 生成新的对象类型,并将它的所有 key 设置为必填。

代码语言:javascript
代码运行次数:0
复制
type RequiredPick<T, K> = any // 完成这个类型

type Obj = {
  a: number;
  b?: string;
  c: boolean;
}

type ResType = RequiredPick<Obj, 'a' | 'b'>;
// 上面的类型要和下面的类型相等
type ExpectedType = {
  a: number;
  b: string; // 注意这里没有可选标识 ?
}

如果你想要真正判断两个类型是否相等,而且是靠肉眼确认,这里有一个用于比较的高级类型:

代码语言:javascript
代码运行次数:0
复制
type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false

Equal 接受两个类型,如果相等返回 true,不相等返回 false。

Pick

我们容易想到 Pick 的实现,Pick 是 TypeScript 内置的一个高级类型。这个类型的实现在我以前的文章《类型体操:探究 TypeScript 内置高级类型》有讲解过。

它的实现如下:

代码语言:javascript
代码运行次数:0
复制
/**
 * 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];
};

Pick 接受两个类型 T 和 K,K 必须为 T 对象的 key 组成的联合类型的子类型。

{ [P in K]: T[P]; } 是对类型进行 重映射,这里的 P in K 表示遍历 K(K 是遍历类型),然后作为重映射类型的新 key,并且将 T[P] 作为值。

关于 Mapped Types(重映射),更多说明可以看这篇官方文档:

https://www.typescriptlang.org/docs/handbook/2/mapped-types.html

可选 -> 必填

Pick 不能将可选的 key 变成必选的,我们需要在这上面做一些调整。

没错,很简单。。。只需要 : 前边加上 -?

实现为:

代码语言:javascript
代码运行次数:0
复制
type RequiredPick<T, K extends keyof T> = {
    [P in K]-?: T[P];
};

除了有 -? 将key 替换为必选,我们还有 -readonly 的写法,将只读 key 转换为普通 key。

然后打个广告,前端大佬神光的 TypeScript 体操教材,如果你想入门的话,这个挺适合,也不贵。

结尾

如果你想练习类型编程,可以尝试做 github 上一个名为 type-challenges 的项目的题目。

我是前端西瓜哥,欢迎关注我,学习更多知识。


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-11-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端西瓜哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Pick
  • 可选 -> 必填
  • 结尾
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档