Permutation<U>
これで中級なん!?になった

似た知識が必要で IsUnion
の方が簡単
使用例
tstype Perm = Permutation<'A' | 'B' | 'C'>;
/**
* ['A', 'B', 'C']
* | ['A', 'C', 'B']
* | ['B', 'A', 'C']
* | ['B', 'C', 'A']
* | ['C', 'A', 'B']
* | ['C', 'B', 'A']
*/
定義
tstype Permutation<T, U = T> =
[T] extends [never] ? []
: T extends T ? [T, ...Permutation<Exclude<U, T>>]
: never;
[T] extends [never]
単純に、 T
が never
かどうか?の条件分岐を書きたい
しかし、単純に T extends never
とは書けない
T extends T
T extends T ? [..]
の形なので、「配列のunion」にしている
型引数 U
「分配前の T
」を保存するために型引数 U
を定義している
分配されて T=1
の時に着目すると、
T extends T
の ?
節は、 [1, ...Permutaion<2|3>]
になる
Permutation<2|3>
は、 [2,3]|[3,2]
なので、
結果として [1,2,3]|[1,3,2]
になる
考え方
まず大枠を見れば、(文字の)Union→(配列の)Unionの変換であることから
すると、distributeされるので、例えば T=1
の時に着眼できる
後は、tail( 2|3
)と再帰を使っていい感じにやろう〜ってことか
難し〜〜

一応リンクしておく

参考
詳しい解説
ぐぐったら引数が配列のやつも出てきた
多分古いのでもうちょい簡潔に書ける