Ts类型体操详讲 之 extends infer (上)

目录

1、数组类型

(1)提取数组中的第一个元素

(2)提取数组中最后一个元素

(3)提取数组中间部分的元素

2、字符串类型

(1)是否以某个前缀开头

(2)提取传入的类型,并返回新的类型

(3)去除首尾空白符


什么是条件提取?

说明:通过extends 对类型进行匹配,将匹配成功的结果保存到infer类型变量中,最后提取这个类型

其实就是我们之前提到的  extends ? 语法 

本节 我们来讲述 Ts类型体操 使用 extends ? 配合 infer 做条件提取,我会通过代码示例 去讲解数组、字符串、函数、构造器、索引等类型如何去使用条件提取

1、数组类型

(1)提取数组中的第一个元素

  type Arr = [1, 2, 3, 4, 5, 6];
  type getArrFirst<T> = T extends unknown[]
    ? T extends [infer First, ...unknown[]]
      ? First
      : unknown
    : never;

  type res2 = getArrFirst<Arr>;

说明:
首先我们定义了一个 Arr 的 类型别名,表示一个包含六个数字(1 到 6)的元组。

然后我们定义了一个类型工具,getArrFirst<T> 它首先检查传入的类型 T 是否是数组,如果 T 不是数组,getArrFirst<T> 的结果就是 never

如果 T 是数组,它会进一步检查 T 是否有一个明确的第一个元素和后续的元素。这是通过

[ infer First, ...unknown [ ] ] 实现的,

其中 infer First 尝试将数组的第一个元素类型分配给新的类型变量 First,而 ...unknown[] 匹配数组的其余部分。

如果这个条件满足(即 T 确实有一个明确的第一个元素),那么 getArrFirst<T> 的结果就是 First

如果不满足(例如,T 是一个空数组 []),则结果是 unknown

(2)提取数组中最后一个元素

  type getArrLast<T extends unknown[]> = T extends [...unknown[], infer Last]
    ? Last
    : never;

(3)提取数组中间部分的元素

  type RemoveTheFirstAndTheLastArr<T extends unknown[]> = T extends [
    unknown,
    ...infer res,
    unknown
  ]
    ? res
    : never;
  type r3 = RemoveTheFirstAndTheLastArr<Arr>;

这几段代码都是相似的,只是提取部分的逻辑有些许差别,我们也可以根据上面去实现

比如 :提取除了第一个元素,返回剩余的部分

2、字符串类型

(1)是否以某个前缀开头

  type StartsWith<
    Prefix extends string,
    str extends string
  > = str extends `${Prefix}${string}` ? true : false;

  type c = "#";
  type d = "#vvv";
  type e = "vvv";
  type resd = StartsWith<c, d>;
  type resc = StartsWith<c, e>;

说明:这段代码中我们 首先去 约束 Prefix str 都应该是string类型,

然后我们通过条件提取 去判断 str 是否以Prefix为前缀 如果正确则返回 true  否则返回 false

(2)提取传入的类型,并返回新的类型

type str = "abcde";
  type InterceptString<
    str extends string,
    form extends string,
    to extends string
  > = str extends `${infer before}${form}${infer after}`
    ? `${before}${to}${after}`
    : str;
  type resi = InterceptString<str, "c", "-to-">;

说明:在这段代码中,我们传入了3个泛型 并 约束为 string 类型,

然后使用条件提取,首先判断 str 是否 可以通过 from 去拆分成 前 中 后 三个部分 如果可以的话 我们返回新的类型  前+to+后,否则返回str 

(3)去除首尾空白符


  type str1 = "    a";
  type str2 = "a   ";
  type str3 = "     a   ";

  // 去除首部空格
  type RemoveSpacePrelude<T extends string> = T extends `${
    | " "
    | "\n"
    | "\t"}${infer str}`
    ? RemoveSpacePrelude<str>
    : T;
  type res1 = RemoveSpacePrelude<str1>;

  // 去除尾部空格
  type RemoveSpaceRump<T extends string> = T extends `${infer str}${
    | " "
    | "\n"
    | "\t"}`
    ? RemoveSpaceRump<str>
    : T;
  type resr = RemoveSpaceRump<str2>;

  // 去除前后空格
  type res4 = RemoveSpacePrelude<RemoveSpaceRump<str3>>;

说明:我们将这个功能拆分为两个类型工具, 方便大家理解

这里简单说下去除首部空格的逻辑:

首先我们先定义了一个去除首部空格的工具RemoveSpacePrelude,他接受一个泛型<T>约束为字符串作为参数,

然后我们使用条件提取 去判断 T 前面是否有空格,如果有的话,我们会去掉前面的空格并将满足条件的通过infer命名为str,然后会进入递归,传入删除空格的新参数str,直到首部没有空格返回 处理好的T

尾部和首部逻辑几乎是一致的。

  • 21
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值