[Typescript] 140. Extreme - Integers Comparator
Implement a type-level integers comparator. We've provided an enum for indicating the comparison result, like this:
- If
a
is greater thanb
, type should beComparison.Greater
. - If
a
andb
are equal, type should beComparison.Equal
. - If
a
is lower thanb
, type should beComparison.Lower
.
Note that a
and b
can be positive integers or negative integers or zero, even one is positive while another one is negative.
enum Comparison {
Greater,
Equal,
Lower,
}
export type IsNegative<T extends number> =
NumberToString<T> extends `-${number}` ? true : false;
export type NumberToString<T extends number> = `${T}`;
type ToNumber<
S extends string,
ACC extends unknown[] = []
> = S extends `${number}`
? S extends `${ACC["length"]}`
? ACC["length"]
: ToNumber<S, [...ACC, unknown]>
: never;
type Absolute<T extends number> = `${T}` extends `-${infer A}` ? ToNumber<A> : T;
type NegativeComparator<T extends number, U extends number, ACC extends unknown[] = []> = T extends U
? Comparison.Equal
: ACC['length'] extends Absolute<T>
? Comparison.Greater
: ACC['length'] extends Absolute<U>
? Comparison.Lower
: NegativeComparator<T, U, [...ACC, unknown]>;
type PositiveComparator<T extends number, U extends number, ACC extends unknown[] = []> = T extends U
? Comparison.Equal
: ACC['length'] extends T
? Comparison.Lower
: ACC['length'] extends U
? Comparison.Greater
: PositiveComparator<T, U, [...ACC, unknown]>;
type Comparator<A extends number, B extends number> = [IsNegative<A>, IsNegative<B>] extends [infer SINGALA, infer SINGALB]
? [SINGALA, SINGALB] extends [true, true]
? NegativeComparator<A, B>
: [SINGALA, SINGALB] extends [false, false]
? PositiveComparator<A, B>
: [SINGALA, SINGALB] extends [true, false]
? Comparison.Lower
: [SINGALA, SINGALB] extends [false, true]
? Comparison.Greater
: never
: never;
/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<Comparator<5, 5>, Comparison.Equal>>,
Expect<Equal<Comparator<5, 6>, Comparison.Lower>>,
Expect<Equal<Comparator<5, 8>, Comparison.Lower>>,
Expect<Equal<Comparator<5, 0>, Comparison.Greater>>,
Expect<Equal<Comparator<-5, 0>, Comparison.Lower>>,
Expect<Equal<Comparator<0, 0>, Comparison.Equal>>,
Expect<Equal<Comparator<0, -5>, Comparison.Greater>>,
Expect<Equal<Comparator<5, -3>, Comparison.Greater>>,
Expect<Equal<Comparator<5, -7>, Comparison.Greater>>,
Expect<Equal<Comparator<-5, -7>, Comparison.Greater>>,
Expect<Equal<Comparator<-5, -3>, Comparison.Lower>>,
Expect<Equal<Comparator<-25, -30>, Comparison.Greater>>,
Expect<Equal<Comparator<15, -23>, Comparison.Greater>>,
Expect<Equal<Comparator<40, 37>, Comparison.Greater>>,
Expect<Equal<Comparator<-36, 36>, Comparison.Lower>>,
Expect<Equal<Comparator<27, 27>, Comparison.Equal>>,
Expect<Equal<Comparator<-38, -38>, Comparison.Equal>>,
]