搞定TS,就靠这个系列(十二)

767 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

序言

这是搞定 TS 第十二篇,如果没有基础的小伙伴想要从零搞定 TS ,请从第一篇开始juejin.cn/post/701033…

第一题

实现一个 ToPath 工具类型,用于把属性访问(. 或 [])路径转换为元组的形式。具体的使用示例如下所示

type ToPath<S extends string> = // 你的实现代码ToPath<'foo.bar.baz'> //=> ['foo', 'bar', 'baz']
ToPath<'foo[0].bar.baz'> //=> ['foo', '0', 'bar', 'baz']

考察知识:

  1. 对infer关键字的应用。
  2. 对模板字符串的灵活使用。

解题思路

  1. 匹配 preCode[0]nextCode
  2. 匹配 preCode.nextCode

题解:

type ToPath<S extends string> = S extends `${infer A}.${infer B}`
  ? [...ToPath<A>, ...ToPath<B>]
  : S extends `${infer A}[${infer B}]`
    ? [A, B]
    : [S]
​
type T1 = ToPath<'foo.bar.baz'> //=> ['foo', 'bar', 'baz']
type T2 = ToPath<'foo[0].bar.baz'> //=> ['foo', '0', 'bar', 'baz']

小结:在匹配到分支1的情况下, preCode 内会存在 可以匹配分支2的情况, 所以需要递归preCode, nextCode也是类似。同时, 匹配到分支2的情况下, preCode 内会存在 可以匹配分支1的情况, 所以需要递归preCode, nextCode也是类似。

第二题

实现一个 Reverse 工具类型,用于对元组类型中元素的位置颠倒,并返回该数组。元组的第一个元素会变成最后一个,最后一个元素变成第一个。

type Reverse<
  T extends Array<any>,
  R extends Array<any> = []
> = // 你的实现代码type R0 = Reverse<[]> // []
type R1 = Reverse<[1, 2, 3]> // [3, 2, 1]

考察知识点

  1. 泛型中的递归应用
  2. infer 关键字的灵活使用

题解

type Reverse<T extends Array<any>> = 
  T extends [infer First, ...infer Rest]
  ? [...Reverse<Rest>, First]
  : [];
​
type R0 = Reverse<[]> // []
type R1 = Reverse<[1, 2, 3]> // [3, 2, 1]
type R2 = Reverse<[1, 2, 3, 4, 5]> //  [5, 4, 3, 2, 1]

小结:我们使用infer 关键字定义第一项和剩余项,把第一项当做剩余属性,剩余属性当做第一项,进行递归,这样就能递归得出结果,注意递归结束条件的设计就行了