小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
序言
这是搞定 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']
考察知识:
- 对infer关键字的应用。
- 对模板字符串的灵活使用。
解题思路
- 匹配 preCode[0]nextCode
- 匹配 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]
考察知识点
- 泛型中的递归应用
- 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 关键字定义第一项和剩余项,把第一项当做剩余属性,剩余属性当做第一项,进行递归,这样就能递归得出结果,注意递归结束条件的设计就行了