Typescriptの型で階乗を計算してみた
C++erにはお馴染みの型で階乗です。
TypescriptはConditional Typeという型定義に条件分岐を付ける機能があり、また型を再帰的に定義できます。そしてstring literalやnumber literalを型として使うことが出来ます。つまり何でもできますね*1
コード
import { IsZero, Next, Prev } from 'simplytyped'; type MulImpl<A extends number, B extends number, C extends number, Temp extends number> = { '2': Temp, '1': MulImpl<A, Prev<B>, Prev<A>, Next<Temp>>, '0': MulImpl<A, B, Prev<C>, Next<Temp>> }[IsZero<B> extends '1' ? '2' : IsZero<C>]; type Mul<A extends number, B extends number> = MulImpl<A, B, Prev<A>, 0>; type Factorial<N extends number> = { '1': 1, '0': Mul<Factorial<Prev<N>>, N> }[IsZero<N>]; const a: Mul<3, 5> = 15; // aの型は15 const b: Factorial<4> = 24; // bの型は24
依存ライブラリは
結果
無事、 Factorial<4>
は 24
という型になりました。
*1:何でもできるとは言ってない