제니릭 튜플 타입 T extends unknown[]가 주어지면, T의 모든 순열을 유니온으로써 만드는 타입을 구현하라.
Given a generic tuple type T extends unknown[], write a type which produces all permutations of T as a union.
type ExcludeByIndex<T extends any[], TargetIndex extends number,Used extends any[]=[]>=
T extends [infer First,...infer Rest]?
TargetIndex extends Used['length']?[...Used,...Rest]
:ExcludeByIndex<Rest,TargetIndex,[...Used,First]>
:Used
type PermutationsOfTupleImplement<T extends unknown[],Index extends any[]=[]> =
T['length'] extends Index['length']?
[]
:[T[Index['length']],...PermutationsOfTupleImplement<ExcludeByIndex<T,Index['length']>>]|
(T['length'] extends [...Index,1]['length']? never : PermutationsOfTupleImplement<T,[...Index,1]>)
type PermutationsOfTuple<T extends any[]>=PermutationsOfTupleImplement<T>
우선 사용처에서 구현용 제네릭을 사용하지 못하게 하기 위해 구현과 실제 타입을 분리했다.
구현을 위해, 배열 내부에 있는 값 중 특정 Index의 요소를 없애는 타입을 구현했다.
이후 매 요소를 순회하면서, 해당 Index에 있는 값을 제일 앞으로, 나머지 값들은 재귀적으로 반환하는 타입을 구현해 문제를 해결하였다.