大家好,我又是你们熟悉的那个梅利奥猪猪!写水文果然是会上瘾的!今天打算两连更,话不多说,继续看题!(PS:本篇文章灵感来自类型体操小册第四节之映射类型)
题目
type MyObject = {
a: number,
b: string,
}
const obj: MyObject = {
a: 1,
b: '2'
}
type MapType<xxx> = xxx
const mapObj: MapType<MyObject> = {
aa: [1, 2, 3],
bb: ['2', '4', '6']
}
老板说请实现MapType!
分析
简单说明题目要干什么
这题看上去很复杂,其实就是要把一个对象类型变成另一个对象类型(说人话!请看下面的代码)
{
a: number,
b: string
}
// 变成下面的
{
aa: [number, number, number]
bb: [string, string, string]
}
第一步
那我们要么先来第一步,变成这样的一个类型,然后在做细节上的处理
{
a: [number]
b: [string]
}
关于这个怎么实现,老样子,架子先搭好
type MapType<xxx> = xxx
第一个xxx就是我们要传入的对象呀,第二个xxx就是实现的部分,直接show code最直观了
type MapType<T> = {
[key in keyof T]: [T[Key]]
}
keyof取到了原本对象有哪些key,所以这边遍历相当于拿到了a和b,然后value该怎么写,因为需要返回数组,手动套一个[],之后就是数组里的类型就是原本对象key对应的类型,所以写成[T[Key]]
来看下结果吧
第二步
第二步,我觉得是最简单的一步,因为根据题干,数组要三项,所以嘛我们就写三项就可以了![T[Key]]变身!!
type MapType<T> = {
[key in keyof T]: [T[Key], T[Key], T[Key]]
}
结果如下
第三步
最后步了,我感觉是这道题最难的地方(其实就是我不熟悉所以才写这篇文章做笔记的哈哈),直接给XDM看代码
type MapType<T> = {
[Key in keyof T as `${Key & string}${Key & string}`]: [T[Key], T[Key], T[Key]]
}
其实从a到aa,从b到bb,无非就是拼接字符串,那我们用模板字符串去实现${变量}${变量},但细心的JYM应该发现了,我们这边还用到了交叉类型Key & string,如果不用这个会报错,这个是为什么呢!因为keyof返回的类型是string | number | symbol的联合类型,但我们这边明显要用到string类型,如何取string类型,和 string 取交叉部分就只剩下 string 了。交叉类型会把同一类型做合并,不同类型舍弃。所以结论就是在交叉处理后,就只剩下string啦,就能拼接啦!
最终结果如下
最终代码如下
type MyObject = {
a: number,
b: string,
}
const obj: MyObject = {
a: 1,
b: '2'
}
type MapType<T> = {
[Key in keyof T as `${Key & string}${Key & string}`]: [T[Key], T[Key], T[Key]]
}
const mapObj: MapType<MyObject> = {
aa: [1, 2, 3],
bb: ['2', '4', '6']
}
课后练习
课后题目
map映射改个华丽胡哨的玩玩
{
a: number,
b: string
}
// 变成下面的
{
test_a: [number, number, number]
test_b: [string, string, string]
}