C++と色々

主にC++やプログラムに関する記事を投稿します。

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

依存ライブラリは

github.com

結果

無事、 Factorial<4>24 というになりました。

Factorial&lt;4&gt;は24という型になりました
Factorial<4>は24という型になりました

*1:何でもできるとは言ってない