@rimbu/common
Version:
Common types and objects used in many other Rimbu packages
240 lines (239 loc) • 9.22 kB
text/typescript
import { Eq } from './internal.cjs';
/**
* An object providing methods to compare two values of type `K`.
* @typeparam K - the value type
*/
export interface Comp<K> {
/**
* Returns 0 if given `value1` and `value2` are equal, a positive value is `value1` is greater than
* `value2`, and a negative value otherwise.
* @param value1 - the first value to compare
* @param value2 - the seconds value to compare
* @example
* ```ts
* const c = Comp.numberComp()
* console.log(c.compare(5, 5))
* // => 0
* console.log(c.compare(3, 5))
* // => -2
* console.log(c.compare(5, 3))
* // => 2
* ```
*/
compare(value1: K, value2: K): number;
/**
* Returns true if this instance can compare given `obj`.
* @param obj - the object to check
* @example
* ```ts
* const c = Comp.numberComp()
* console.log(c.isComparable(5))
* // => true
* console.log(c.isComparable('a'))
* // => false
* ```
*/
isComparable(obj: any): obj is K;
}
export declare namespace Comp {
/**
* Returns the default Comp instance, which is the Comp.anyDeepComp() instance.
*/
function defaultComp(): Comp<any>;
/**
* Returns a default number Comp instance that orders numbers naturally.
* @example
* ```ts
* const c = Comp.numberComp();
* console.log(c.compare(3, 5))
* // => -2
* ```
*/
function numberComp(): Comp<number>;
/**
* Returns a default boolean Comp instance that orders booleans according to false < true.
* @example
* ```ts
* const c = Comp.booleanComp();
* console.log(c.compare(false, true) < 0)
* // => true
* console.log(c.compare(true, true))
* // => 0
* ```
*/
function booleanComp(): Comp<boolean>;
/**
* Returns a default bigint Comp instance that orders bigint numbers naturally.
*/
function bigIntComp(): Comp<bigint>;
/**
* Returns a Comp instance converts values to string with JSON.stringify, and orders the resulting string naturally.
*/
function anyStringJSONComp<T>(): Comp<T>;
/**
* Returns a `Comp` instance that compares strings based on the string's `localeCompare` method.
* @param locales - (optional) a locale or list of locales
* @param options - (optional) see String.localeCompare for details
*/
function stringComp(...args: ConstructorParameters<typeof Intl.Collator>): Comp<string>;
/**
* Returns a `Comp` instance that compares strings in a case-insensitive way.
*/
function stringCaseInsensitiveComp(): Comp<string>;
/**
* Returns a string Comp instance that orders strings according to their indexed char codes.
*/
function stringCharCodeComp(): Comp<string>;
/**
* Returns a any Comp instance that orders any according to their toString values.
*/
function anyToStringComp(): Comp<any>;
/**
* Returns a Comp instance that orders objects with a `valueOf` method according to the given `valueComp` instance for the valueOf values.
* @param cls - the constructor of the values the Comp instance can compare
* @param valueComp - (optional) the Comp instance to use on the .valueOf values
*/
function createValueOfComp<T extends {
valueOf(): V;
}, V>(cls: {
new (): T;
}, valueComp?: Comp<V>): Comp<T>;
/**
* Returns a Date Comp instance that orders Dates according to their `.valueOf` value.
*/
function dateComp(): Comp<Date>;
/**
* Returns a Comp instance for Iterable objects that orders the Iterables by comparing the elements with the given `itemComp` Comp instance.
* @param itemComp - (optional) the Comp instance to use to compare the Iterable's elements.
* @example
* ```ts
* const c = Comp.iterableComp();
* console.log(c.compare([1, 3, 2], [1, 3, 2]))
* // => 0
* console.log(c.compare([1, 2, 3, 4], [1, 3, 2]) < 0)
* // => true
* ```
*/
function iterableComp<T>(itemComp?: Comp<T>): Comp<Iterable<T>>;
/**
* Returns a Comp instance for objects that orders the object keys according to the given `keyComp`, and then compares the corresponding
* values using the given `valueComp`. Objects are then compared as follows:<br/>
* starting with the smallest key of either object:<br/>
* - if only one of the objects has the key, the object with the key is considered to be larger than the other<br/>
* - if both objects have the key, the values are compared with `valueComp`. If the values are not equal, this result is returned.<br/>
*
* if the objects have the same keys with the same values, they are considered equal<br/>
* @param keyComp - (optional) the Comp instance used to order the object keys
* @param valueComp - (optional) the Comp instance used to order the object values
* @example
* ```ts
* const c = Comp.objectComp();
* console.log(c.compare({ a: 1 }, { a: 1 }))
* // => 0
* console.log(c.compare({ a: 1 }, { a: 2 }) < 0)
* // => true
* console.log(c.compare({ b: 5 }, { a: 2 }) < 0)
* // => true
* console.log(c.compare({ a: 1, b: 2 }, { b: 5 }) < 0)
* // => true
* console.log(c.compare({ a: 1, b: 2 }, { b: 2, a: 1 }))
* // => 0
* ```
*/
function objectComp(options?: {
keyComp?: Comp<any>;
valueComp?: Comp<any>;
}): Comp<Record<any, any>>;
/**
* Returns a Comp instance that compares any value using default comparison functions, but never recursively compares
* Iterables or objects. In those cases, it will use the stringComp instance.
* @example
* ```ts
* const c = Comp.anyFlatComp();
* console.log(c.compare({ a: 1, b: 1 }, { b: 1, a: 1 }) < 0)
* // => true
* // First object is smaller because the objects are converted to a string with and then compares the resulting string.
* ```
*/
function anyFlatComp<T>(): Comp<T>;
/**
* Returns a Comp instance that compares any value using default comparison functions. For Iterables and objects, their elements are compared
* only one level deep for performance and to avoid infinite recursion.
* @example
* ```ts
* const c = Comp.anyShallowComp();
* console.log(c.compare({ a: 1, b: 1 }, { b: 1, a: 1 }))
* // => 0
* console.log(c.compare([{ a: 1, b: 1 }], [{ b: 1, a: 1 }]) < 0)
* // => true
* // First object is smaller because the objects are converted to a string and then compares the resulting string.
* ```
*/
function anyShallowComp<T>(): Comp<T>;
/**
* Returns a Comp instance that compares any value using default comparison functions. For Iterables and objects, their elements are compared
* recursively.
* @note can become slow with large nested arrays and objects, and circular structures can cause infinite loops
* @example
* ```ts
* const c = Comp.anyDeepComp();
* console.log(c.compare({ a: 1, b: 1 }, { b: 1, a: 1 }))
* // => 0
* console.log(c.compare([{ a: 1, b: 1 }], [{ b: 1, a: 1 }]))
* // => 0
* ```
*/
function anyDeepComp<T>(): Comp<T>;
/**
* Returns a Comp instance that extends the given `comp` instance with the capability to handle `undefined` values, where undefined is considered to be smaller
* than any other value, and equal to another undefined.
* @param comp - the Comp instance to wrap
* @example
* ```ts
* const c = Comp.withUndefined(Comp.numberComp())
* console.log(c.compare(undefined, 5) < 0)
* // => true
* console.log(c.compare(undefined, undefined))
* // => 0
* ```
*/
function withUndefined<T>(comp: Comp<T>): Comp<T | undefined>;
/**
* Returns a Comp instance that extends the given `comp` instance with the capability to handle `null` values, where null is considered to be smaller
* than any other value, and equal to another null.
* @param comp - the Comp instance to wrap
* @example
* ```ts
* const c = Comp.withNull(Comp.numberComp())
* console.log(c.compare(null, 5) < 0)
* // => true
* console.log(c.compare(null, null))
* // => 0
* ```
*/
function withNull<T>(comp: Comp<T>): Comp<T | null>;
/**
* Returns a Comp instance the reverses the order of the given `comp` instance.
* @param comp - the Comp instance to wrap
* @example
* ```ts
* const c = Comp.invert(Comp.numberComp())
* console.log(c.compare(3, 5) > 0)
* // => true
* console.log(c.compare(5, 5))
* // => 0
* ```
*/
function invert<T>(comp: Comp<T>): Comp<T>;
/**
* Returns an `Eq` equality instance thet will return true when the given `comp` comparable instance returns 0.
* @param comp - the `Comp` comparable instance to convert
* @example
* ```ts
* const eq = Comp.toEq(Comp.objectComp())
* console.log(eq({ a: 1, b: 2 }, { b: 2, a: 1 }))
* // => true
* ```
*/
function toEq<T>(comp: Comp<T>): Eq<T>;
}