Created
February 9, 2023 22:06
-
-
Save MasterTuto/47ddcc240def44d32a4213b886a3993c to your computer and use it in GitHub Desktop.
Calculator using TypeScript type system
This file contains 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 Compare<A extends number, B extends number, X extends any[]=[], Y extends any[]=[]> = X['length'] extends A | |
? Y['length'] extends B ? 0 : -1 | |
: Y['length'] extends B ? 1 : Compare<A, B, [any, ...X], [any, ...Y]> | |
type IsLower<A extends number, B extends number> = Compare<A, B> extends -1 ? true : false; | |
type IsHigher<A extends number, B extends number> = Compare<A, B> extends 1 ? true : false; | |
type CreateArray<N extends number, A extends any[]=[]> = A['length'] extends N ? A : CreateArray<N, [any, ...A]> | |
type Add<A extends number, B extends number> = [...CreateArray<A>, ...CreateArray<B>]['length']; | |
type Subtract<A extends number, B extends number,> = CreateArray<B> extends infer ArrB extends any[] ? ( | |
ArrB['length'] extends 0 ? A : ( | |
ArrB extends [a: infer BX, ...b: infer BY] ? ( | |
CreateArray<A> extends [a: infer AX, ...b: infer AY] ? ( | |
Subtract<AY['length'], BY['length']> | |
) : never | |
) : never | |
) | |
) : never; | |
type Multiply<A extends number, B extends number, R extends number = 0> = B extends 0 ? R | |
: Add<A, R> extends infer XR extends number ? | |
Multiply<A, Subtract<B, 1>, XR> : | |
never; | |
type Divide<N extends number, M extends number, V extends number = 0, P extends number=0> = IsHigher<Multiply<V, M>, N> extends true | |
? P : ( | |
Add<V, 1> extends infer X extends number ? | |
Divide<N, M, X, V> | |
: never | |
); | |
type Operator = '+' | '-' |'*' | '/'; | |
type Calc<A extends number, Op extends Operator, B extends number> = Op extends '+' ? ( | |
Add<A, B> | |
) : ( | |
Op extends '-' ? ( | |
Subtract<A, B> | |
) : ( | |
Op extends '*' ? ( | |
Multiply<A, B> | |
) : Divide<A, B> | |
) | |
) | |
type FivePlusTwo = Calc<5, '+', 2>; | |
type FiveMinusThree = Calc<5, '-', 3>; | |
type FiveTimesFour = Calc<5, '*', 4>; | |
type EightByFour = Calc<8, '/', 4>; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment