精读《type challenges - easy》

本文详细解析了TypeScript的type challenges中easy级别的多个题目,包括Pick、Readonly、First Of Array、Length of Tuple等,通过实际案例深入理解TS的类型系统和泛型。强调通过练习提升TS思维习惯,解决类型问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TS 强类型非常好用,但在实际运用中,免不了遇到一些难以描述,反复看官方文档也解决不了的问题,至今为止也没有任何一篇文档,或者一套教材可以解决所有犄角旮旯的类型问题。为什么会这样呢?因为 TS 并不是简单的注释器,而是一门图灵完备的语言,所以很多问题的解决方法藏在基础能力里,但你学会了基础能力又不一定能想到这么用。

解决该问题的最好办法就是多练,通过实际案例不断刺激你的大脑,让你养成 TS 思维习惯。所以话不多说,我们今天从 type-challenges 的 Easy 难度题目开始吧。

精读

Pick

手动实现内置 Pick<T, K> 函数,返回一个新的类型,从对象 T 中抽取类型 K:

interface Todo {
  title: string
  description: string
  completed: boolean
}

type TodoPreview = MyPick<Todo, 'title' | 'completed'>

const todo: TodoPreview = {
    title: 'Clean room',
    completed: false,
}

结合例子更容易看明白,也就是 K 是一个字符串,我们需要返回一个新类型,仅保留 K 定义的 Key。

第一个难点在如何限制 K 的取值,比如传入 T 中不存在的值就要报错。这个考察的是硬知识,只要你知道 A extends keyof B 这个语法就能联想到。

第二个难点在于如何生成一个仅包含 K 定义 Key 的类型,你首先要知道有 { [A in keyof B]: B[A] } 这个硬知识,这样可以重新组合一个对象:

// 代码 1
type Foo<T> = {
  [P in keyof T]: T[P]
}

只懂这个语法不一定能想出思路,原因是你要打破对 TS 的刻板理解,[K in keyof T] 不是一个固定模板,其中 keyof T 只是一个指代变量,它可以被换掉,如果你换掉成另一个范围的变量,那么这个对象的 Key 值范围就变了,这正好契合本题的 K

// 代码 2(本题答案)
type MyPick<T, K in keyof T> = {
  [P in K]: T[P]
}

这个题目别看知道答案后简单,回顾下还是有收获的。对比上面两个代码例子,你会发现,只不过是把代码 1 的 keyof T 从对象描述中提到了泛型定义里而已,所以功能上没有任何变化,但因为泛型可以由用户传入,所以代码 1 的 P in keyof T 因为没有泛型支撑,这里推导出来的就是 T 的所有 Keys,而代码 2 虽然把代码挪到了泛型,但因为用的是 extends 描述,所以表示 P 的类型被约束到了 T 的 Keys,至于具体是什么,得看用户代码怎么传。

所以其实放到泛型里的 K 是没有默认值的,而写到对象里作为推导值就有了默认值。泛型里给默认值的方式如下:

// 代码 3
type MyPick<T, K extends keyof T = keyof T> = {
  [P in K]: T[P]
}

也就是说,这样 MyPick<Todo> 就也可以正确工作并原封不动返回 Todo 类型,也就是说,代码 3 在不传第二个参数时,与代码 1 的功能完全一样。仔细琢磨一下共同点与区别,为什么代码 3 可以做到和代码 1 功能一样,又有更强的拓展性,你对 TS 泛型的实战理解就上了一个台阶。

Readonly

手动实现内置 Readonly<T> 函数,将对象所有属性设置为只读:

interface Todo {
  title: string
  description: string
}

const todo: MyReadonly<Todo> = {
  title: "Hey",
  description: "foobar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值