[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 than b, type should be Comparison.Greater.
  • If a and b are equal, type should be Comparison.Equal.
  • If a is lower than b, type should be Comparison.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>>,
]

 

posted @ 2022-12-19 15:32  Zhentiw  阅读(13)  评论(0编辑  收藏  举报