Last active
May 31, 2021 15:38
-
-
Save rjdestigter/64eaec0fcdb003bff1cad2000c787efd to your computer and use it in GitHub Desktop.
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 Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
type IsNumber<A extends string> = A extends `${Digit}${infer T}` ? T extends "" ? true : IsNumber<T> : false | |
type NaN = "NaN" | |
type ToLiteralNumber<T extends string> = IsNumber<T> extends true ? MkTuple<T> extends true[] ? MkTuple<T>['length'] : NaN : NaN | |
type MkTuple<N extends string | number, T extends true[] = []> = `${T['length']}` extends `${N}` ? T : MkTuple<N, [true, ...T]> | |
type Add<A extends number, B extends number> = [...MkTuple<A>, ...MkTuple<B>]['length'] | |
type SubtractOne<A extends number> = MkTuple<A> extends [infer _, ...infer R] ? R['length'] : 0 | |
type Subtract<A extends number, B extends number> = B extends 0 ? A : Subtract<SubtractOne<A>, SubtractOne<B>> | |
type IsGreaterThenOrEqual<A extends number, B extends number> = | |
A extends 0 ? B extends 0 ? true : false : A extends B ? true : IsGreaterThenOrEqual<SubtractOne<A>, B> | |
type IsGreaterThen<A extends number, B extends number> = | |
A extends B ? false : IsGreaterThenOrEqual<SubtractOne<A>, B> | |
type Multiply<A extends number, B extends number, R extends number = B> = | |
A extends 0 | |
? 0 | |
: B extends 0 | |
? 0 | |
: A extends 1 | |
? R | |
: B extends 1 | |
? R | |
: Add<R, B> extends number | |
? Multiply<SubtractOne<A>, B, Add<R, B>> | |
: B | |
type Fraction<L extends number, N extends number, D extends number> = [L, N, D] | |
type AnyFraction = Fraction<number, number, number> | |
type Rest<A extends number, B extends number> = [A, B] | |
type DivideWithRest<A extends number, B extends number, Acc extends number = 0> = A extends B | |
? Add<Acc, 1> extends number ? Rest<Add<Acc, 1>, 0> : 0 | |
: IsGreaterThen<B, A> extends true | |
? Rest<Acc, A> | |
: Add<Acc, 1> extends number ? DivideWithRest<Subtract<A, B>, B, Add<Acc, 1>> : never | |
// [result, rest, divisor] | |
type Divide<A extends number, B extends number> = DivideWithRest<A, B> extends infer Result ? Result extends Rest<infer T, infer U> ? Fraction<T, U, B> : Result : never | |
type GetDecimals<T extends AnyFraction, Level extends number = 0> = Level extends 4 ? [] : T extends [infer L, infer N, infer D] | |
? N extends number | |
? D extends number | |
? N extends 0 | |
? [L] | |
: Multiply<N, 10> extends number | |
? Divide<Multiply<N, 10>, D> extends [number, number, number] | |
? Add<1, Level> extends number ? [L, ...GetDecimals<Divide<Multiply<N, 10>, D>, Add<1, Level>>] : never | |
: [] | |
: [] | |
: [] | |
: never | |
: never | |
type Join<A extends number[]> = A extends [infer B, ...infer C] ? B extends number ? `${B}${C extends number[] ? Join<C> : ""}` : "" : "" | |
type ShowFraction<T extends AnyFraction> = GetDecimals<T> extends [infer L, ...infer D] ? L extends number ? D extends number[] ? `${L}.${Join<D>}` : never : never : never | |
type expr0_25 = ShowFraction<[0, 1, 4]> | |
type expr1_333 = ShowFraction<Divide<4, 3>> | |
type expr25 = Add<12, 13> | |
type expr15 = Subtract<20, 5> | |
type exprTrue = IsGreaterThen<Add<25, 1>, 25> | |
type expr8 = Multiply<2, 4> | |
declare const fifteen : Multiply<3, 5> | |
const fifteen_ : Multiply<5, 3> = fifteen | |
const fifteen__ : Add<7, 8> = fifteen | |
const fifteen___ : Divide<30, 2>[0] = fifteen | |
const fifteen____ : Subtract<21, 6> = fifteen | |
type expr84_seems_to_be_max = Add<42, 42> | |
type expr42 = ToLiteralNumber<"42"> | |
type exprNaN = ToLiteralNumber<"abc"> | |
type expr15_ = Subtract<ToLiteralNumber<"33">, Multiply<ToLiteralNumber<"3">, 6>> | |
type expr27 = Add<ToLiteralNumber<"12">, Subtract<ToLiteralNumber<"33">, Multiply<ToLiteralNumber<"3">, 6>>> | |
function add <A extends number, B extends number>(a: A, b: B): Add<A, B> { | |
return (a + b) as any | |
} | |
const nine: 9 = add(4, 5) | |
const nine_: Multiply<3, 3> = add(4, 5) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment