ts
type N_ZERO = []
type NUM = N_ZERO | [ NUM ]
type INC < N > = [ N ]
type DEC < N > = (
N extends [ infer M ]
? M
: never
)
{
let x : DEC < INC < N_ZERO >> = [];
}
type ADD < N , M > = (
M extends N_ZERO
? N
:
// ADD<INC<N>, DEC<N>>
// Type alias 'ADD' circularly references itself.
{
0 : ADD < INC < N >, DEC < M >>,
1 : never
}[ N extends any ? 0 : 1 ]
)
{
let x : ADD <[[]], [[]]> = [[[]]]; // 1 + 1 == 2
}
type N_ONE = INC < N_ZERO >;
type MUL < N , M , S = N_ZERO > = (
M extends N_ZERO
? S
:
{
0 : MUL < N , DEC < M >, ADD < S , N >>,
1 : never
}[ N extends any ? 0 : 1 ]
)
type N_TWO = INC < N_ONE >
type N_THREE = INC < N_TWO >
{
let x : MUL < N_ONE , N_ONE > = [[]]; // 1 * 1 == 1
} {
let x : MUL < N_TWO , N_ONE > = [[[]]]; // 2 * 1 == 2
} {
let x : MUL < N_ONE , N_TWO > = [[[]]]; // 1 * 2 == 1
} {
let x : MUL < N_TWO , N_TWO > = [[[[[]]]]]; // 2 * 2 == 4
}
ts
type N_0 = N_ZERO ;
type N_1 = N_ONE ;
type N_2 = N_TWO ;
type N_3 = [ N_2 ];
type N_4 = [ N_3 ];
type N_5 = [ N_4 ];
type N_6 = [ N_5 ];
type N_7 = [ N_6 ];
type N_8 = [ N_7 ];
type N_9 = [ N_8 ];
type N_TEN = [ N_9 ];
type DIGITS2 < N , M > = MUL < N , N_TEN , M >
// try "N - M", return answer or null
type MINUS < N , M > = (
M extends N_0
? N
: (
{
0 : null ,
1 : MINUS < DEC < N >, DEC < M >>
}[ N extends N_0 ? 0 : 1 ]
)
)
{
let x : MINUS < N_5 , N_2 > = {} as N_3
} {
let x : MINUS < N_2 , N_5 > = null ;
}
type DIVIDE <
N , M ,
Q = N_0 ,
N1 = MINUS < N , M >
> = (
{
0 : [ Q , N ],
1 : DIVIDE < N1 , M , INC < Q >>
}[ N1 extends null ? 0 : 1 ]
)
{
let x : DIVIDE < MUL < N_3 , N_4 >, N_TEN > = {} as [ N_1 , N_2 ]
}
{
let x : DIVIDE < MUL < N_7 , N_8 >, N_TEN > = {} as [ N_5 , N_6 ]
// Type instantiation is excessively deep and possibly infinite.
}
I can do 5 * 6 30, but not 6 * 7 42.
This page is auto-translated from /nishio/TypeScriptの型で自然数を作る using DeepL. If you looks something interesting but the auto-translated English is not good enough to understand it, feel free to let me know at @nishio_en . I’m very happy to spread my thought to non-Japanese readers.