持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
前言
在学习typescript的过程当中,有一个github库对其类型的学习特别有帮助,是一个有点类似于leetcode的刷题项目,能够在里面刷各种关于typescript类型的题目,在之前篇文章中,我们完成了中等的第十九题,今天来做中等的第二十题 527-medium-append-to-object
下面这个是类型体操github仓库:
527-medium-append-to-object
import type { Equal, Expect } from '@type-challenges/utils'
type test1 = {
key: 'cat'
value: 'green'
}
type testExpect1 = {
key: 'cat'
value: 'green'
home: boolean
}
type test2 = {
key: 'dog' | undefined
value: 'white'
sun: true
}
type testExpect2 = {
key: 'dog' | undefined
value: 'white'
sun: true
home: 1
}
type test3 = {
key: 'cow'
value: 'yellow'
sun: false
}
type testExpect3 = {
key: 'cow'
value: 'yellow'
sun: false
isMotherRussia: false | undefined
}
type cases = [
Expect<Equal<AppendToObject<test1, 'home', boolean>, testExpect1>>,
Expect<Equal<AppendToObject<test2, 'home', 1>, testExpect2>>,
Expect<Equal<AppendToObject<test3, 'isMotherRussia', false | undefined>, testExpect3>>,
]
从README和测试用例中能够得出,我们需要实现一个工具函数 AppendToObject 能够为对象添加属性。
利用 JS 进行模拟学习
在JS中对对象添加key值比较简单,我们只需要简单的将题目提供的key和val拼凑到对象中就好了。
function appendToObject(obj,key,val){
return {
...obj,
key:val
}
}
实现 AppendToObject
相对于 JS 那种直接拼接的方式 TS 并不支持,但是我们可以回忆一下之前是怎么进行对象操作的。
在之前我们能够通过映射类型来对对象进行操作,比方说:
{[P in keyof T]:T[P]}
这样的方式去便利对象中的所有键值,那么是否能够在后面的 keyof T
进行一些操作,来使得遍历的次数增加一次,而这一次,我们就能够加入入参中的key。
对于 keyof T
会获得的是对象所有key值的联合类型,而 in keyof T
的语法就是会遍历后面的这个联合类型,那么我们就可以通过在联合上一个key值,来增加一次遍历次数,而这一次遍历的key也正是入参传入的key
type AppendToObject<T, U extends string | symbol, V> =
{ [P in (keyof T) | U]: T[P] }
然后就是需要处理对象的新val,用之前的 T[P]
遍历到新的key的时候肯定是获取不到东西的,会进行报错
因为原对象上并不存在这个建,所有我们需要使用条件类型进行判断,当这个键值不存在原本的对象的时候,就需要使用外部传入的val。
type AppendToObject<T, U extends string | symbol, V> = { [P in (keyof T) | U]: P extends keyof T
? T[P]
: V
}
这样测试用例就全部都通过了。
知识点
关于上述提到了部分的知识点:
- 对象遍历
- 条件类型
今天的题目比较简单,只要能够理解之前的映射类型的运行方式,应该是能够很容易进行解答的。
总结
今天我们做完了中等的第二十题,题目属于比较常规的问题,主要在于对于之前的映射类型的学习是否够足,还不够了解的可以先去参考一下之前的文章,深入学习一下映射类型。