@ts-java/comparator
Version: 
A pure Typescript implementation of the Java `Comparator` functional interface.
159 lines (156 loc) • 8.31 kB
text/typescript
/**
 * This interface imposes a total ordering on the objects of each class that implements it.
 * This ordering is referred to as the class's natural ordering, and the object's compareTo method is referred to as
 * its natural comparison method.
 */
interface Comparable<T> {
    /**
     * Compares this object with the specified object for order.
     * @param other the object to be compared.
     * @returs a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
     */
    compareTo(other: T): number;
}
/**
 * All possible values that can be compared by default.
 * @see {@link Comparable}
 */
type ComparableValue = Comparable<any> | number | string | boolean | Date;
/**
 * All possible keys that can be compared used by the keyExtractor.
 */
type ComparableKeyOf<T> = {
    [K in keyof T]: T[K] extends ComparableValue ? K : never;
}[keyof T];
/**
 * All possible values that can be returned by the keyExtractor.
 */
type ComparableValueOf<T> = T[ComparableKeyOf<T>];
/**
 * A function that extracts a comparable value from an object.
 */
type ComparableKeyExtractor<T, U extends ComparableValueOf<T>> = (object: Pick<T, ComparableKeyOf<T>>) => ComparableValue & U;
/**
 * A JavaScript implementation of the Java Comparator interface. Due to the lack of Functional Interfaces in JavaScript,
 * this has to be implemented as an abstract class.
 * The class has a single abstract method, compare, that must be implemented by the user.
 * In addition to that, it also has a number of static methods that can be used to create new comparators.
 *
 * For more information, see the Java documentation.
 * @see https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html
 */
declare abstract class Comparator<T> {
    #private;
    /**
     * Accepts a function that extracts a comparable value from type T and returns a new Comparator that compares objects by that value in natural order.
     * @param keyExtractor a function that extracts a comparable value from type T.
     * @returns a new Comparator that compares objects by the value extracted by the keyExtractor function in natural order.
     */
    static comparing<T, U extends ComparableValueOf<T> = ComparableValueOf<T>>(keyExtractor: ComparableKeyExtractor<T, U>): Comparator<T>;
    /**
     * Accepts a function that extracts a comparable value from type T and a Comparator that compares objects by that value.
     * Uses the given Comparator to compare the extracted values.
     * @param keyExtractor a function that extracts a comparable value from type T.
     * @param keyComparator a Comparator that compares the objects by the value extracted by the keyExtractor function.
     * @returns a new Comparator that compares objects by the value extracted by the keyExtractor function using the given Comparator.
     */
    static comparing<T, U extends ComparableValueOf<T> = ComparableValueOf<T>>(keyExtractor: ComparableKeyExtractor<T, U>, keyComparator: Comparator<U>): Comparator<T>;
    /**
     * Returns a Comparator that compares {@link ComparableValue Comparable} objects by their natural order.
     * @returns a new Comparator that compares objects by their natural order.
     * @throws a {@link NullPointerException} if either of the objects is null.
     * @throws an Error if the objects are not of the same type or are not comparable by natural order.
     *
     * @example
     * ```typescript
     * const numbers = [1,5,3,2,4];
     * numbers.toSorted(Comparator.naturalOrder().compare); // [1,2,3,4,5]
     * ```
     */
    static naturalOrder<T extends ComparableValue = ComparableValue>(): Comparator<T>;
    /**
     * Returns a Comparator that compares {@link ComparableValue Comparable} objects by their reverse order.
     * This is equivalent to calling `Comparator.naturalOrder().reversed()`.
     * @returns a new Comparator that compares objects by their reverse order.
     * @see {@link Comparator.naturalOrder}
     * @example
     * ```typescript
     * const numbers = [1,5,3,2,4];
     * numbers.toSorted(Comparator.reverseOrder().compare); // [5,4,3,2,1]
     * ```
     */
    static reverseOrder<T extends ComparableValue = ComparableValue>(): Comparator<T>;
    /**
     * A null-friendly comparator that compares objects using the given Comparator, putting null values first.
     * @param comparator the comparator that will be used to compare the objects.
     * @returns a new Comparator that compares objects using the given Comparator, with nulls first.
     * @example
     * ```typescript
     * const numbers = [1,5,3,2,4,null];
     * numbers.toSorted(
     *  Comparator.nullFirst(
     *    Comparator.naturalOrder()
     *  ).compare
     * ); // [null,1,2,3,4,5]
     * ```
     */
    static nullFirst<U>(comparator: Comparator<U>): Comparator<U | null>;
    /**
     * A null-friendly comparator that compares objects using the given Comparator, putting null values last.
     * @param comparator the comparator that will be used to compare the objects.
     * @returns a new Comparator that compares objects using the given Comparator, with nulls last.
     * @example
     * ```typescript
     * const numbers = [1,5,null,3,2,4];
     * numbers.toSorted(
     *  Comparator.nullLast(
     *    Comparator.naturalOrder()
     *  ).compare
     * ); // [1,2,3,4,5,null]
     */
    static nullLast<U>(comparator: Comparator<U>): Comparator<U | null>;
    /**
     * Compares its two arguments for order.
     * @param a the first object to be compared.
     * @param b the second object to be compared.
     * @returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
     * @throws a {@link NullPointerException} if one of the values is null and this comparator does not permit null arguments
     * @throws a {@link TypeError} if the arguments' types prevent them from being compared by this comparator
     */
    abstract compare(a: T, b: T): number;
    /**
     * Returns a new Comparator that imposes the reverse ordering of this Comparator.
     * @returns a Comparator that imposes the reverse ordering of this Comparator.
     * @example
     * ```typescript
     * const comparator = Comparator.naturalOrder();
     * const numbers = [1,5,3,2,4];
     * numbers.toSorted(
     *  comparator.reversed().compare
     * ); // [5,4,3,2,1]
     */
    reversed(): Comparator<T>;
    /**
     * Returns a lexicographic-order comparator with a function that extracts a comparable value.
     * If this Comparator considers two elements equal, the next one is used.
     * @param keyExtractor a function that extracts a comparable value from type T and compares objects by that value in natural order if the previous comparison is equal.
     * @returns a new Comparator that compares objects using the given Comparator if the previous comparison is equal.
     */
    thenComparing<U extends ComparableValueOf<T>>(keyExtractor: ComparableKeyExtractor<T, U>): Comparator<T>;
    /**
     * Returns a lexicographic-order comparator with another comparator.
     * If this Comparator considers two elements equal, the next one is used.
     * @param other the Comparator to be used if the previous comparison is equal.
     * @returns a new Comparator that compares objects using the given Comparator if the previous comparison is equal.
     */
    thenComparing(other: Comparator<T>): Comparator<T>;
    /**
     * Returns a lexicographic-order comparator with a function that extracts a comparable value and a Comparator.
     * If this Comparator considers two elements equal, the provided Comparator is used to compare the objects by the value extracted by the keyExtractor function.
     * @param keyExtractor a function that extracts a comparable value from type T.
     * @param keyComparator the Comparator to be used if the previous comparison is equal.
     * @returns a new Comparator that compares objects by the value extracted by the keyExtractor function using the given Comparator if the previous comparison is equal.
     */
    thenComparing<U extends ComparableValueOf<T>>(keyExtractor: ComparableKeyExtractor<T, U>, keyComparator: Comparator<U>): Comparator<T>;
}
export { type Comparable, Comparator };