Skip to content

Instantly share code, notes, and snippets.

@MasterTuto
Created February 9, 2023 22:06
Show Gist options
  • Save MasterTuto/47ddcc240def44d32a4213b886a3993c to your computer and use it in GitHub Desktop.
Save MasterTuto/47ddcc240def44d32a4213b886a3993c to your computer and use it in GitHub Desktop.
Calculator using TypeScript type system
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