携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情
1. 引言
接着上一节中,接下来我们继续Ts中等篇的题型练习
https://github.com/type-challenges/type-challenges/blob/main/README.zh-CN.md 提供的TypeScript 类型体操姿势合集题型,目的是为了让大家更好的了解TS的类型系统,编写自己的类型工具,或者单纯的享受挑战的乐趣!
2. 题型
- Combination:给定一个字符串数组,进行排列和组合。它对于像video controlsList这样的道具类型也很有用
type Keys = Combination<['foo', 'bar', 'baz']> // expected to be `"foo" | "bar" | "baz" | "foo bar" | "foo bar baz" | "foo baz" | "foo baz bar" | "bar foo" | "bar foo baz" | "bar baz" | "bar baz foo" | "baz foo" | "baz foo bar" | "baz bar" | "baz bar foo"`
思路:
首先该题考验我们的是数组元素的多种不同排列组合方式;由于传入的参数是一个数组我们就可以采用${I} ${Combination<[], Exclude<A, I>>} 的方式递归操作数组剩余的内容,在此之前我们要使用infer 关键字来退下I类型是否为数组类型,如果是的会直接回抛,避免U和A的类型不对导致的报错问题,在这个解决的思路中我们巧妙的通过I | 来返回所有的联合类型并且配合状态检测,规避了很多类型不匹配的报错问题,该题结束,完成;
解答:
type Combination<T extends string[], A = T[number], U = A> =
U extends infer I extends string
? I | `${I} ${Combination<[], Exclude<A, I>>}`
:never
type Demo = Combination<['foo', 'bar', 'baz']// type Demo = 'foo' | 'bar' | 'baz' | 'foo bar' | 'foo bar baz' | 'foo baz' | 'foo baz bar' | 'bar foo' | 'bar foo baz' | 'bar baz' | 'bar baz foo' | 'baz foo' | 'baz foo bar' | 'baz bar' | 'baz bar foo'
- Subsequence:给定一个唯一元素数组,返回所有可能的子序列。
子序列是可以从数组派生的序列,只需删除一些元素或不删除元素,而不改变其余元素的顺序。
type A = Subsequence<[1, 2]> // [] | [1] | [2] | [1, 2]
思路: 首先该题考验的还是数组内部元素的所有组合方案,直接递归就好了并且我们在采用 | 连接,这样每次递归都会生成其中一项,这样就可以获得一个多种组合类型值的联合类型,通过每次递归执行并且每次都抽取其中一项后合并值操作,完成。 解答:
type Subsequence<T extends any[]> =
T extends [infer F, ...infer Rest]
? [F, ...Subsequence<Rest>] | Subsequence<Rest>
: T
type Demo = Subsequence<[1, 2]> // type Demo = [] | [1] | [2] | [1, 2]
type Demo2 = Subsequence<[1, 2, 3]> // type Demo2 = [] | [1] | [2] | [1, 2] | [3] | [1, 3] | [2, 3] | [1, 2, 3]