ts类型体操学习笔记之写个map练练手

477 阅读2分钟

大家好,我又是你们熟悉的那个梅利奥猪猪!写水文果然是会上瘾的!今天打算两连更,话不多说,继续看题!(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,所以这边遍历相当于拿到了ab,然后value该怎么写,因为需要返回数组,手动套一个[],之后就是数组里的类型就是原本对象key对应的类型,所以写成[T[Key]]

来看下结果吧

a.png

第二步

第二步,我觉得是最简单的一步,因为根据题干,数组要三项,所以嘛我们就写三项就可以了![T[Key]]变身!!

type MapType<T> = {
    [key in keyof T]: [T[Key], T[Key], T[Key]]
}

结果如下

b.png

第三步

最后步了,我感觉是这道题最难的地方(其实就是我不熟悉所以才写这篇文章做笔记的哈哈),直接给XDM看代码

type MapType<T> = {
    [Key in keyof T as `${Key & string}${Key & string}`]: [T[Key], T[Key], T[Key]]
}

其实从aaa,从bbb,无非就是拼接字符串,那我们用模板字符串去实现${变量}${变量},但细心的JYM应该发现了,我们这边还用到了交叉类型Key & string,如果不用这个会报错,这个是为什么呢!因为keyof返回的类型是string | number | symbol的联合类型,但我们这边明显要用到string类型,如何取string类型,和 string 取交叉部分就只剩下 string 了。交叉类型会把同一类型做合并,不同类型舍弃。所以结论就是在交叉处理后,就只剩下string啦,就能拼接啦!

最终结果如下

c.png

最终代码如下

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]
}

答案链接

typescript的playground链接在此