Last active
July 4, 2021 07:00
-
-
Save tars0x9752/03b2b744a491c80078a63ce41e60b055 to your computer and use it in GitHub Desktop.
natural-number-within-ts-types
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 配列の先頭以外を抜き取る型 | |
| type Tail<T extends any[]> = T extends [any, ...infer U] ? U : [] | |
| type Zero = [] | |
| type Succ = 'Succ' | |
| type Next<T extends Nat> = [...T, Succ] // どっちかというとNextでやってることがSuccなんだけど,,,簡単のため妥協 | |
| // 自然数 Nat | |
| type Nat = Zero | Succ[] | |
| // Nat の値を人間が読めるように変換する型 | |
| type NatResolver<T extends Nat> = T['length'] | |
| // Nat を数値から生成 | |
| type NatGenerator<N extends number, Acc extends Nat = Zero> = Acc['length'] extends N | |
| ? Acc | |
| : NatGenerator<N, [Succ, ...Acc]> | |
| // 加算 | |
| type Add<T extends Nat, U extends Nat> = [...T, ...U] | |
| // 減算(マイナスになる場合はゼロ) | |
| type Subtract<T extends Nat, U extends Nat> = U extends Zero ? T : Subtract<Tail<T>, Tail<U>> | |
| // 乗算 | |
| type Multiply<T extends Nat, U extends Nat, Acc extends Nat = Zero> = U extends Zero | |
| ? Zero | |
| : U extends [Succ] | |
| ? Add<Acc, T> | |
| : Multiply<T, Tail<U>, Add<Acc, T>> | |
| // 除算(切り捨て) | |
| type Divide<T extends Nat, U extends Nat, Acc extends Nat = Zero> = U extends Zero | |
| ? never | |
| : T extends [Succ] | Zero | |
| ? Acc | |
| : Divide<Subtract<T, U>, U, Next<Acc>> | |
| // 使用例 | |
| type One = Next<Zero> | |
| type Two = Add<One, One> | |
| type Three = Add<Two, One> | |
| type Four = Multiply<Two, Two> | |
| type Five = Add<Two, Three> | |
| type Six = Multiply<Two, Three> | |
| type Ten = NatGenerator<10> | |
| type OneHundred = Multiply<Ten, Ten> | |
| type n1 = NatResolver<One> // 1 | |
| type n2 = NatResolver<Two> // 2 | |
| type n3 = NatResolver<Three> // 3 | |
| type n4 = NatResolver<Four> // 4 | |
| type n5 = NatResolver<Five> // 5 | |
| type n6 = NatResolver<Six> // 6 | |
| type n10 = NatResolver<Ten> // 10 | |
| type n100 = NatResolver<OneHundred> // 100 | |
| type n24 = NatResolver<Multiply<Six, Four>> // 24 | |
| type n20 = NatResolver<Subtract<Multiply<Six, Four>, Four>> // 20 | |
| type n0_1 = NatResolver<Multiply<Zero, Six>> // 0 | |
| type n0_2 = NatResolver<Subtract<Two, Six>> // 0 | |
| type div_1 = NatResolver<Divide<Ten, Two>> // 10/2 => 5 | |
| type div_2 = NatResolver<Divide<Multiply<Six, Four>, Four>> // 24/4 => 6 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment