TypeScript类型体操--数组攻略(中)

大家好,我是苏先生,一名热爱钻研、乐于分享的前端工程师,跟大家分享一句我很喜欢的话:人活着,其实就是一种心态,你若觉得快乐,幸福便无处不在

前言

前边三篇文章我们一共实现了22个工具类型,按照本专栏的规划,还差77个...

本节我们继续学习数组相关的类型编程

image.png

提示

对于语法层面的知识点本系列(类型体操开头的标题)不会展开说明哈,可以自行搜索学习其他大佬的优质文章或者等我后续更新补充

isTuple

  • 功能

判断一个类型是否是元组

  • 实现

首先它接收一个泛型参数T

type IsTuple<T>

我们不应该限制T的类型,如果T是一个非元组,则直接返回false就好了

type IsTuple<T> = T extends any[] ? true : false

目前,对于readonly修饰符,我们的IsTuple会返回false

image.png

要解决这个问题,我们只需要将条件类型相应的增加readonly修饰符就可以了,这是因为带有修饰符的元组表示的范围更小,你可以认为它是没有修饰符的父类型

image.png

最后,我们思考数组和元组的区别,看下图,一个数组类型的length的返回类型为number

image.png

但是对于元组,length取到的却是一个具体的数字

image.png

为此,我们需要对length进行单独的处理

type IsTuple<T> = T extends readonly any[] ? 
                    number extends T['length'] 
                    ?
                    false
                    : true
                    : false
  • 使用示例
image.png

lastIndexOf

  • 功能

找到元素在元组中的位置,找不到返回-1

  • 实现

首先,它接收两个泛型参数T、U

type LastIndexOf<T,U>

接着,我们对泛型参数进行约束:对于泛型T,应该是一个数组类型,而泛型U则是any类型

type LastIndexOf<T exyends any[],U>

然后,我们要想办法拿到最后一个元素,在上一节中我们介绍过,通过扩展运算可以达到该目的,如下,L即是最后一个元素,此时我们只需要借助infer关键字就可以拿到元素对应的类型了

[...infer F,infer L]

既然我们已经拿到了最后一个元素,那就可以与U进行比较判断了,我们知道,当两个类型一样或具有父子关系时,通过extends可以得到true,伪代码如下

L extends U ? '得到其对应的位置' : '递归'

我们分别来思考extends分两个分支:

1-成立时,取位置

上一节我们在分析Last工具类型时介绍过,T["length"]能够取到当前数组的长度,且它与元素对应的位置的T["length"]的取值减去1,这恰好是F的长度

2-不成立时,进行递归

这个比较简单,我们只需要将数组的最后一位删掉重新调用LastIndexOf就行了,好巧不巧的是,它又刚好是F

综上所述,最终实现如下

type LastIndexOf<T extends any[],U> = T extends [...infer F,infer L] ? 
                                        L extends U 
                                            ?
                                            F['length']
                                            : LastIndexOf<F,U>
                                        : -1
  • 使用示例
image.png

includes

  • 功能

判断元素是否在元组中

  • 实现

首先,它接收两个泛型参数T、U

type Includes<T,U>

泛型T的参数需要约束为数组类型

type Includes<T extends any[],U> 

接着我们要想办法拿到数组中的每一个元素与U进行比较,正如前文分析的那样,这肯定要用到类型递归

T extends [...infer F,infer L] ? '判断是否存在' : '递归'

事实上,按照上文LastIndexOf的实现思路这会变得很容易,不过由于多个条件类型会让代码变得难以阅读。所以,我们选择提取出一个公共类型来专门负责两个元素的比较

type IsEqual<V,Item> = V extends Item ? true : false

最后按照LastIndexOf的套路,我们比较完一个,就把已经比较过的元素丢弃掉,并重新调用includes,最终实现如下

type Includes<Value extends any[], Item> =
    IsEqual<Value[0], Item> extends true
        ? true
        : Value extends [Value[0], ...infer rest]
            ? Includes<rest, Item>
            : false;
  • 使用示例
image.png

下期预告

最后一个就当作是一个随堂练习啦,我们放在下一节中进行实现(ps:欢迎在评论区晒出你的实现思路🤩)

Fill

  • 功能

类型版本的数组填充

  • 示例
type Result = Fill<[1, 2, 3], 'a'> // ['a', 'a', 'a']
type Result2 = Fill<[1, 2, 3], 'a',1> // [1, 2, 'a']
type Result3 = Fill<[1, 2, 3], 'a',1,2> // [1, 'a', 3]
  • 提示

类型递归


如果本文对您有用,希望能得到您的❤


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,188评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,464评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,562评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,893评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,917评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,708评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,430评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,342评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,801评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,976评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,115评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,804评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,458评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,008评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,135评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,365评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,055评论 2 355

推荐阅读更多精彩内容