持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情
前言
在学习typescript的过程当中,有一个github库对其类型的学习特别有帮助,是一个有点类似于leetcode的刷题项目,能够在里面刷各种关于typescript类型的题目,在之前篇文章中,我们完成了中等的第二十二题,今天来做中等的第二十三题 531-medium-string-to-union
下面这个是类型体操github仓库:
531-medium-string-to-union
import type { Equal, Expect } from '@type-challenges/utils'
type Foo = {
a: number
b: string
}
type Bar = {
b: number
c: boolean
}
type cases = [
Expect<Equal<Merge<Foo, Bar>, {
a: number
b: number
c: boolean
}>>,
]
从README和测试用例中能够得出,我们需要实现一个工具函数 Merge 能够整合两个对象中的属性,并且第二个参数中的属性会覆盖掉第一个参数里面的同名属性。
利用 JS 进行模拟学习
JS 中存在很多种方法可以将对象进行拼接,主要可以通过解构,对象方法,或者循环遍历,这里就简单的举两个例子。
利用对象方法:
function merge1(obj1:any,obj2:any){
return Object.assign(obj1,obj2)
}
利用循环:
function merge2(obj1:any,obj2:any){
let obj3:any = {}
for(let i of Object.keys(obj1)){
obj3[i] = obj1[i]
}
for(let i of Object.keys(obj2)){
obj3[i] = obj1[i]
}
return obj3
}
实现 Merge
那么根据 JS 的思路,在 TS 当中我们也能够通过多种方法来实现这个工具类型
Oimt
首先我们可以利用 TS 提供的 Omit 工具类型,先剔除掉第一个对象中含有的第二个对象的属性,然后将两个对象利用交叉类型进行合并。
type Merge2<F, S> = Omit<F,keyof S> & S
但是这期的测试似乎需要将类型铺平,而不是是直接这样。
所以我们还需要进行一次操作来将类型平铺:
type Merge<F, S> = {[P in keyof Merge2<F, S>]:Merge2<F, S>[P]}
type Merge2<F, S> = Omit<F,keyof S> & S
这样就能够通过测试了。
重映射
再者就是通过重映射来实现,在之前我们讲过重映射能够对映射类型的key值进行检验,不满足的就可以通过赋值为 never 进行排除,这也就可以应用到这个上面,将第一个对象中重复的键值进行剔除。
type Merge1<F, S> = {
[P in keyof S]:S[P]
} & {
[P in keyof F as P extends keyof S ? never : P]:F[P]
}
然后和第一种方法一样,需要做出平铺,这里就不再过多讲述,一样的操作就能够通过测试了。
知识点
关于上述提到了部分的知识点:
- Omit
- 映射类型
- 重映射
- 交叉类型
今天的题目设计的比较多的就是交叉类型,对于交叉类型在 TS 的对象处理中是很重要的概念,还不了解的可以优先去了解一下。
总结
今天我们做完了中等的第二十三题,题目设计到了比较多的映射类型的细节以及交叉类型的使用,对于这两个知识之前都是有介绍过的,就看能不能灵活的进行运用。