// @ts-nocheck type StringBool = "true" | "false"; interface AnyNumber { prev?: any; isZero: StringBool; } interface PositiveNumber { prev: any; isZero: "false"; } type IsZero = TNumber["isZero"]; type Next = { prev: TNumber; isZero: "false" }; type Prev = TNumber["prev"]; type Add = { true: T2; false: Next, T2>>; }[IsZero]; // Computes T1 * T2 type Mult = MultAcc; type MultAcc = { true: TAcc; false: MultAcc, T2, Add>; }[IsZero]; // Computes max(T1 - T2, 0). type Subt = { true: T1; false: Subt, Prev>; }[IsZero]; interface SubtResult< TIsOverflow extends StringBool, TResult extends AnyNumber, > { isOverflowing: TIsOverflow; result: TResult; } // Returns a SubtResult that has the result of max(T1 - T2, 0) and indicates whether there was an overflow (T2 > T1). type SafeSubt = { true: SubtResult<"false", T1>; false: { true: SubtResult<"true", T1>; false: SafeSubt, Prev>; }[IsZero]; }[IsZero]; type _0 = { isZero: "true" }; type _1 = Next<_0>; type _2 = Next<_1>; type _3 = Next<_2>; type _4 = Next<_3>; type _5 = Next<_4>; type _6 = Next<_5>; type _7 = Next<_6>; type _8 = Next<_7>; type _9 = Next<_8>; type Digits = { 0: _0; 1: _1; 2: _2; 3: _3; 4: _4; 5: _5; 6: _6; 7: _7; 8: _8; 9: _9; }; type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9; type NumberToType = Digits[TNumber]; // I don't know why typescript complains here. type _10 = Next<_9>; type _100 = Mult<_10, _10>; type Dec2 = Add< Mult<_10, NumberToType>, NumberToType >; function forceEquality() {} function forceTrue() {} //forceTrue, Subt, _3>, Dec2<5,7>> >>(); //forceTrue, Subt, _3>, Dec2<5,7>> >>(); type Mod = { true: _0; false: Mod2>; }[IsZero]; type Mod2< TNumber extends AnyNumber, TModNumber extends AnyNumber, TSubtResult extends SubtResult, > = { true: TNumber; false: Mod; }[TSubtResult["isOverflowing"]]; type Equals = Equals2< TNumber1, TNumber2, SafeSubt >; type Equals2< TNumber1 extends AnyNumber, TNumber2 extends AnyNumber, TSubtResult extends SubtResult, > = { true: "false"; false: IsZero; }[TSubtResult["isOverflowing"]]; type IsPrime = IsPrimeAcc< TNumber, _2, Prev> >; type IsPrimeAcc = { false: { true: "false"; false: IsPrimeAcc, Prev>; }[IsZero>]; true: "true"; }[IsZero]; forceTrue>>(); forceTrue>>(); forceTrue>>(); forceTrue>>(); forceTrue>>(); forceTrue>>(); forceTrue>>();