Created
May 5, 2022 21:10
-
-
Save Grubba27/a9dd3928f3cd996072df4d3b3c3f3e3b to your computer and use it in GitHub Desktop.
Simple calculator made in ts
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 Reverse<A> = | |
`${A}` extends `${infer AH}${infer AT}` | |
? `${Reverse<AT>}${AH}` : A | |
type Digs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | |
type DigsNext<I = Digs, R = {}> = | |
I extends [infer Head, infer Next, ...infer Tail] | |
? DigsNext<[Next, ...Tail], R & Record<Head, Next>> | |
: { [K in keyof R]: R[K] } | |
type DigsPrev = { [K in keyof DigsNext as DigsNext[K]]: K } | |
type ToNumber< | |
S extends string, | |
L extends number[] = []> | |
= `${L['length']}` extends S | |
? L['length'] | |
: ToNumber<S, [...L, 0]> | |
type GreaterThan< | |
T extends number, | |
U extends number, | |
C extends unknown[] = [] | |
> = | |
T extends U | |
? false | |
: C['length'] extends T | |
? false | |
: C['length'] extends U | |
? true | |
: GreaterThan<T, U, [...C, 1]>; | |
type AddOne<A> = | |
A extends `${infer AH}${infer AT}` | |
? AH extends '9' ? `0${AddOne<AT>}` : `${DigsNext[AH]}${AT}` | |
: `1` | |
type SubOne<A> = | |
A extends `${infer AH}${infer AT}` | |
? AH extends '0' ? `9${SubOne<AT>}` : `${DigsPrev[AH]}${AT}` | |
: never | |
type Sub< | |
A extends string, | |
B extends string, | |
R extends string = "0" | |
> = | |
B extends R | |
? A | |
: Sub<SubOne<A>, B, AddOne<R>>; | |
type Add<A, B> = | |
A extends `${infer AH}${infer AT}` ? | |
B extends `${infer BH}${infer BT}` | |
? BH extends '0' ? `${AH}${Add<AT, BT>}` : Add<AddOne<A>, SubOne<B>> | |
: A : B | |
type Mul<A, B, R = '0'> = | |
A extends '0' ? R : | |
B extends '0' ? R : | |
A extends `${infer AH}${infer AT}` | |
? AH extends '0' ? Mul<AT, `0${B}`, R> : Mul<SubOne<A>, B, Add<R, B>> | |
: R | |
type Multiply<A extends string | number | bigint, B extends string | number | bigint> = | |
Reverse<Mul<Reverse<A>, Reverse<B>>> | |
type Division< | |
W extends string, | |
D extends string, | |
Q extends string = '0' | |
> = | |
W extends '0' | |
? Q | |
: Division<Sub<W, D>, D, AddOne<Q>> | |
type Power< | |
V extends string, | |
P extends string, | |
A extends string = V> = | |
P extends '1' | |
? A | |
: P extends '0' | |
? '1' | |
: Power<V, SubOne<P>, Multiply<V, A>> | |
// Log<10, 100> = 2 | |
type Log< | |
B extends string, | |
L extends string, | |
I extends string = "0", | |
PA extends string = "0"> = | |
L extends "1" | |
? "0" | |
: L extends PA | |
? I | |
: GreaterThan<ToNumber<PA>,ToNumber<L>> extends true | |
? never | |
: Log<B, L, AddOne<I>, Power<B, AddOne<I>>>; | |
const $: Power<'2', '4'> = "16"; | |
const _: Power<'2', '3'> = "8"; | |
type OpDict<A extends string, B extends string> = { | |
'Div': Division<A, B>, | |
'Mul': Multiply<A, B>, | |
'Sum': Add<A, B>, | |
'Sub': Sub<A, B>, | |
'Log': Log<A, B>, | |
'Pow': Power<A, B> | |
}; | |
type Calculator | |
<Operation extends keyof OpDict<string, string>, | |
A extends string = '0', | |
B extends string = '0' | |
> = OpDict<A, B>[Operation]; | |
const teste: Calculator<'Mul', '2', '2'> // 4 | |
const teste: Calculator<'Mul', '2', '8'> // 16 | |
const teste: Calculator<'Sum', '2', '4'> // 6 | |
const teste: Calculator<'Sub', '9', '4'> // 5 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment