type-challengesの「Permutation」で詰まった話 - Qiita
この記事はHRBrain Advent Calendar 2022カレンダー2の7日目の記事です。 株式会社HRBrainでは毎週TypeChanllengeを行っています。 この取り組みを紹介した記事があるので興味がある方は御覧ください。 その中で「Permutation」という特段難しい問題に詰まったので紹介します。 復習がてら記事にしました。 TypeScriptの型の問題集のようなリポジトリです。 Vue.js コアチームメンバーでVitest、Slidevの作成者である@antfu7 さんという方が開発しています。 Union 型を Union 型の値の順列を含む配列に変換する順列型を実装する問題です。 こちらが最もコメントの多く、recommendのラベルが付けられている回答です。 本記事もこちらを参考にさせて頂いています。 丁寧に解説してくださっているので、興味がある方は下記のリンクを御覧ください。 まとめては理解しにくいと思うので分けて解説します。 もう既にわけがわかりませんね これは一言でいうと Tがneverか判定している処理 です。 下記の式ででいけるのでは?と思う方がいるかも知れませんが、期待通りの動作はしません。 TSのPlaygroundを見ていただくと理解が早いと思います。 型引数に渡されたneverは条件分岐の際、無視されるので機能しません。 そのため評価される前にタプル型にして、条件分岐できるようにしています。 かなりhack的な方法ですが、neverを判別するにはこれしか無いようです。 詳しくはこちらをご覧ください。 TypeScriptはunion型を型引数に渡すと下記のように分散する性質があります。 それを利用して K extends Kにunion型を渡してそれぞれ条件分岐を行わせることができます。 このように渡されたunion型でループ処理のようなことをさせています。 'A'が型引数 Kに渡されたとします。 再帰的にPermutationの引数として T('A' | 'B' | 'C')から K('A')を除外した'B' | 'C'を型引数として渡しています。 配列に K('A') とPermutationの結果を展開しています。 この再帰的な流れを理解するのに下記の表がとてもわかりやすかったのでぜひご覧下さい。 最終的に全てのパターンが結合され順列を網羅した型になります。 type-challengesをやっていて着実に型表現力がついてきていると日々実感しています。 TypeScriptに自身がない方、TS力を上げたい方は一度チャレンジしてみてはいかがでしょうか?
https://qiita.com/riku0202/items/2867d412effab9042848