TS试炼-10
摘要:
包含:Combination key type(组合键类型)、Permutations of Tuple(元组全排列)
1、Combination key type(组合键类型)
ts
Combs<['cmd', 'ctrl', 'opt', 'fn']> // 'cmd ctrl' | 'cmd opt' | 'cmd fn' | 'ctrl opt' | 'ctrl fn' | 'opt fn'
实现
ts
type Combs<T extends any[]> = T extends [infer F extends string, ...infer R extends string[]]
? `${F} ${R[number]}` | Combs<R>
: never;
2、Permutations of Tuple(元组全排列)
ts
PermutationsOfTuple<[1, number, unknown]>
// 结果:
// | [1, number, unknown]
// | [1, unknown, number]
// | [number, 1, unknown]
// | [unknown, 1, number]
// | [number, unknown, 1]
// | [unknown, number ,1]
第一种方法(容易理解)
ts
// 将元组的每一项再包一层
type WrapArray<T extends any[]> = T extends [infer S, ...infer O] ? [[S], ...WrapArray<O>] : [];
// 判断两个类型是否相同
type MyEqual<X, Y> =
(<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
// 从元组中剔除指定类型
type MyExclued<T extends any[], U> = T extends [infer S, ...infer O]
? MyEqual<S, U> extends true
? MyExclued<O, U>
: [S, ...MyExclued<O, U>]
: [];
// 获取全排列
type MyPermutationsOfTuple<T extends any[], U = T[number]> = [U] extends [never]
? []
: U extends U
? [U extends any[] ? U[0] : never, ...MyPermutationsOfTuple<MyExclued<T, U>>]
: [];
type PermutationsOfTuple<
T extends unknown[],
U extends unknown[] = WrapArray<T>,
> = MyPermutationsOfTuple<U>;
解释:
与简单排列原理相同,只是需要转换一下,因为此处元组直接取number并不是原始每一项的联合。
第二种方法
ts
// 将类型插入到元组的每一项后面
type Insert<T extends unknown[], U> = T extends [infer F, ...infer L]
? [F, U, ...L] | [F, ...Insert<L, U>]
: [U];
type PermutationsOfTuple<T extends unknown[], R extends unknown[] = []> = T extends [
infer F,
...infer L,
]
? PermutationsOfTuple<L, Insert<R, F> | [F, ...R]>
: R;
解释:
通过:Insert<R, F> | [F, ...R]
得到所有结果,其中:
R
表示已经处理的字符的所有排序可能,
Insert<R, F>
表示当前项不再第一位的所有可能,
[F, ...R]
表示当前项在第一位的所有可能
第三种方式
ts
type PermutationsOfTuple<T extends unknown[], Prev extends unknown[] = []> = T extends [
infer First,
...infer Rest,
]
?
| [First, ...PermutationsOfTuple<[...Prev, ...Rest]>] // 当前项作为第一项与其他项全排列
| (Rest extends [] ? never : PermutationsOfTuple<Rest, [...Prev, First]>) // 剩余参数继续处理,让每一项都能成为第一项
: [];
解释:
假设元组只有一项:[any]
此时:只会走此:[First, ...PermutationsOfTuple<[...Prev, ...Rest]>]
,相当于:[any, ...PermutationsOfTuple<[]>]
结果就是[any]
假设为两项:[unknown, any]
此时[First, ...PermutationsOfTuple<[...Prev, ...Rest]>]
,相当于:[unknown, ...PermutationsOfTuple<[any]>]
,根据第一步结果,此时结果为[unknown, any]
。
在看(Rest extends [] ? never : PermutationsOfTuple<Rest, [...Prev, First]>)
。此时Rest
为[any]
,结果相当于PermutationsOfTuple<[any], [unknown]>)
,最终结果为[any, unknown]
将两个结果联合:[unknown, any] | [any, unknown]
假设为三项:[never, unknown, any]
此时[First, ...PermutationsOfTuple<[...Prev, ...Rest]>]
,相当于:[never, ...PermutationsOfTuple<[unknown, any]>]
,根据第二步结果,此时结果为[never, ...([unknown, any] | [any, unknown])]
,即:[never, unknown, any] | [never, any, unknown]
。
在看。此时Rest
为[unknown, any]
,结果相当于PermutationsOfTuple<[unknown, any], [never]>)
,即:[unknown, ...PermutationsOfTuple<[...[never], ...[any]]>] | [any, ...PermutationsOfTuple<[...[never, unknow], ...[]]>]
以此类推:[First, ...PermutationsOfTuple<[...Prev, ...Rest]>]
为第一项在第一位,剩余项的全排列
(Rest extends [] ? never : PermutationsOfTuple<Rest, [...Prev, First]>)
:其他项在第一位,其他参数的全排列
第四种方式
ts
type PermutationsOfTuple<T extends any[], R extends 0[] = []> = T extends []
? []
: R['length'] extends T['length']
? never
: T extends [infer First, ...infer Rest]
? [First, ...PermutationsOfTuple<Rest>] | PermutationsOfTuple<[...Rest, First], [...R, 0]>
: never;
解释:
同第三种:感觉稍微好理解点。
3、
ts
实现
ts
4、
ts
实现
ts
5、
ts
实现
ts
6、
ts
实现
ts
7、
ts
实现
ts
8、
ts
实现
ts
9、
ts
实现
ts
10、
ts
实现
ts
评论
0条评论
暂无内容,去看看其他的吧~