type PermutationsOfTuple<T extends any[], R extends any[] = []> = T extends []
? []
: R['length'] extends T['length']
? never
: T extends [infer First, ...infer Rest]
? [First, ...PermutationsOfTuple<Rest>] | PermutationsOfTuple<[...Rest, First], [...R, any]>
: never
Solution by 2083335157 #34964
type PermutationsOfTuple<T extends unknown[], U extends unknown[] = []> = T extends [infer R, ...infer rest] ?
[R, ...PermutationsOfTuple<[...rest, ...U]>] | (rest['length'] extends 0 ? never : PermutationsOfTuple<rest, [...U, R]>) : T
Solution by ouzexi #34148
type PermutationsOfTuple<T extends unknown[], SaveArr extends any[]=[]> = T extends [infer A, infer B, ...infer C]
?PermutationsOfTuple<[B,...C],[...SaveArr,A]> | PermutationsOfTuple<[A,...C],[B,...SaveArr]>
:[...T,...SaveArr] |[...SaveArr,...T]
//#A넣고
//B넣고
//C넣고
//a넣고
//C넣고
//B넣고
Solution by bananana0118 #33170
type PermutationsOfTuple<T, K extends keyof T = keyof T & `${number}`>
= [K] extends [never] ? []
: {[I in K]: [T[I], ...PermutationsOfTuple<T, Exclude<K, I>>]}[K]
Solution by teamchong #33062
type PermutationsOfTuple<
T extends unknown[],
C extends any[] = []
> = T extends [infer F, ...infer R]
?
| [F, ...PermutationsOfTuple<R, []>]
| ([...C, any]["length"] extends T["length"]
? never
: PermutationsOfTuple<[...R, F], [...C, any]>)
: [];
Solution by vangie #32205
提供一个解题思路
type Permutation<T, K=T> = [T] extends [never] ? [] : (K extends K ? [K, ...Permutation<Exclude<T, K>>] : never);
type Test1 = ([any, unknown, 1])[number]; // any
type Test2 = ([1, 2, 3, 4])[number]; // 1 | 2 | 3 | 4
其中Test2才是我们想要的结果。
type WrapArray<T extends any[]> = T extends [infer S, ...infer O] ? [[S], ...WrapArray<O>] : [];
type Test1 = WrapArray<[any, unknown]> // [[any], [unknown]]
type Test2 = Test1[number]; // [unknown] | [any]
这样我们就可以通过联合类型的分布式计算迭代出每个元素了
type Test = Exclude<[any]|[unknown], [unknown]>; // never
但是我们可以直接通过他原本的数组剔除其中的元素,比如从[[unknown], [any], 1]中剔除[unknown]得到其他元素[[any], 1],代码如下:
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 Test = MyExclued<[[unknown], [any], 1], [unknown]> //[[any], 1]
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], O = U> = [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>;
最后别忘了一开始我们给数组中的每个元素包了一层数组,所以取值的时候取U[0]即可。
Solution by tarotlwei #31765
// [1, number, unknown] => [0, 1, 2] 拿到索引数组
type GetIndex<T extends unknown[], U extends number[] = []> = T extends [
any,
...infer R
]
? GetIndex<R, [...U, U["length"]]>
: U;
// [0, 1, 2] => [0, 1, 2] | [0, 2, 1] | [1, 0, 2] | [1, 2, 0] | [2, 0, 1] | [2, 1, 0] 打乱索引数组
type GetUnion<T extends number[], U = T[number], K = U> = [U] extends [never]
? []
: U extends K
? [U, ...GetUnion<[], Exclude<K, U>>]
: [];
// [0, 1, 2] => [1, number, unknown] 根据索引取对应项值,得到最终结果
type PermutationsOfTuple<
T extends unknown[],
U = GetUnion<GetIndex<T>>
> = U extends [infer F extends number, ...infer R]
? [T[F], ...PermutationsOfTuple<T, R>]
: [];
type Res = PermutationsOfTuple<[1, number, unknown]>;
Solution by moonpoet #31038
// your answers
// type PermutationsOfUnion<T, U = T> =
// [T] extends [never]
// ? []
// : U extends T
// ? [U, ...PermutationsOfUnion<Exclude<T, U>>]
// : []
type GetIndexUnion<T extends unknown[]> =
T extends [infer _, ...infer R]
? R['length'] | GetIndexUnion<R>
: never
type GetTupleByIndexUnion<T extends unknown[], U extends number, I = U> =
[U] extends [never]
? []
: I extends U
? [T[I], ...GetTupleByIndexUnion<T, Exclude<U, I>>]
: []
type PermutationsOfTuple<T extends unknown[]> = GetTupleByIndexUnion<T, GetIndexUnion<T>>
Solution by milletlovemouse #30946
// your answers
type InsertToArr<Left extends unknown[], S, Right extends unknown[] = []> = Left extends [...infer Rest, infer Last] ? [...Left, S, ...Right] | InsertToArr<Rest, S, [Last, ...Right]> : [S, ...Right]
type PermutationsOfTuple<T extends unknown[]> = T extends [infer First, ...infer Rest] ? InsertToArr<PermutationsOfTuple<Rest>, First> : []
Solution by Kakeru-Miyazaki #30922
type PermutationsOfTuple<T extends unknown[]> = T extends [infer F, ...infer Rest, infer L]
?
| [F, ...PermutationsOfTuple<Rest>, L]
| [L, ...PermutationsOfTuple<Rest>, F]
| [F, L, ...PermutationsOfTuple<Rest>]
| [L, F, ...PermutationsOfTuple<Rest>]
| [...PermutationsOfTuple<Rest>, F, L]
| [...PermutationsOfTuple<Rest>, L, F]
: T;
Solution by leejaehyup #30877
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
Solution by jiangshanmeta #29713
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]>)
: []
Solution by Sun79 #29657