UNPKG

alistair

Version:
607 lines (603 loc) 19.1 kB
/** * An immutable variant of the native `Map` class where all mutating operations * return new instances instead of modifying the original map. * * @template K - The type of keys in the map * @template V - The type of values in the map * * @example * ```typescript * const map1 = new ImmutableMap([['a', 1], ['b', 2]]); * const map2 = map1.set('c', 3); * * console.log(map1.get('c')); // undefined * console.log(map2.get('c')); // 3 * ``` */ declare class ImmutableMap<K, V> { /** * Internal Map instance used for storage * @private */ private readonly map; /** * A shared empty immutable map instance. Using `never` type ensures * it can be safely cast to ImmutableMap<K, V> for any K and V. * * @example * ```typescript * const emptyStringMap = ImmutableMap.Empty as ImmutableMap<string, number>; * const emptyUserMap = ImmutableMap.Empty as ImmutableMap<UserId, User>; * ``` */ static readonly Empty: ImmutableMap<never, never>; /** * Creates a new ImmutableMap instance, optionally from an iterable * * This is perfect for usage with `useState` as React calls the `.from()` function * when initializing the state, but TypeScript lets us set the generic types * inline. * * @example * ```typescript * const [map, setMap] = useState(ImmutableMap.from<string, number>); * ``` * * @param iterable - Optional iterable of initial [key, value] pairs * @returns A new ImmutableMap instance */ static from: <K_1, V_1>(iterable?: Iterable<[K_1, V_1]>) => ImmutableMap<K_1, V_1>; /** * Returns the number of key/value pairs in the map * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * console.log(map.size); // 2 * ``` */ get size(): number; /** * Creates a new ImmutableMap instance * * @param iterable - Optional iterable of initial [key, value] pairs * * @example * ```typescript * const map1 = new ImmutableMap([['a', 1], ['b', 2]]); * const map2 = new ImmutableMap(new Map([['x', 10], ['y', 20]])); * const empty = new ImmutableMap<string, number>(); * ``` */ constructor(iterable?: Iterable<[K, V]>); /** * Creates a new map with the specified key/value pair added or updated * * @param key - The key to set * @param value - The value to associate with the key * @returns A new ImmutableMap containing the new key/value pair * * @example * ```typescript * const map1 = new ImmutableMap([['a', 1]]); * const map2 = map1.set('b', 2); * const map3 = map2.set('a', 10); // Updates existing key * * console.log(map1.get('b')); // undefined * console.log(map2.get('b')); // 2 * console.log(map3.get('a')); // 10 * ``` */ set(key: K, value: V): ImmutableMap<K, V>; /** * Retrieves the value associated with a key * * @param key - The key to look up * @returns The value associated with the key, or undefined if the key doesn't exist * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * console.log(map.get('a')); // 1 * console.log(map.get('x')); // undefined * ``` */ get(key: K): V | undefined; /** * Checks if a key exists in the map * * @param key - The key to check * @returns `true` if the key exists, `false` otherwise * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * console.log(map.has('a')); // true * console.log(map.has('x')); // false * ``` */ has(key: K): boolean; /** * Creates a new map with the specified key removed * * @param key - The key to remove * @returns A new ImmutableMap with the key/value pair removed * * @example * ```typescript * const map1 = new ImmutableMap([['a', 1], ['b', 2]]); * const map2 = map1.delete('a'); * * console.log(map1.has('a')); // true * console.log(map2.has('a')); // false * ``` */ delete(key: K): ImmutableMap<K, V>; /** * Creates a new empty map * * @returns A new empty ImmutableMap * * @example * ```typescript * const map1 = new ImmutableMap([['a', 1], ['b', 2]]); * const map2 = map1.clear(); * * console.log(map1.size); // 2 * console.log(map2.size); // 0 * ``` */ clear(): ImmutableMap<K, V>; /** * Executes a callback for each key/value pair in the map * * @param callbackfn - Function to execute for each entry * @param thisArg - Value to use as `this` when executing the callback * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * const results: string[] = []; * map.forEach((value, key) => { * results.push(`${key}=${value}`); * }); * console.log(results); // ['a=1', 'b=2'] * ``` */ forEach(callbackfn: (value: V, key: K) => void, thisArg?: any): void; /** * Returns an iterator of the map's keys * * @returns An iterator containing the keys * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * const keys = [...map.keys()]; * console.log(keys); // ['a', 'b'] * ``` */ keys(): IterableIterator<K>; /** * Returns an iterator of the map's values * * @returns An iterator containing the values * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * const values = [...map.values()]; * console.log(values); // [1, 2] * ``` */ values(): IterableIterator<V>; /** * Returns an iterator of the map's entries * * @returns An iterator containing [key, value] pairs * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * for (const [key, value] of map.entries()) { * console.log(`${key}=${value}`); // Logs: 'a=1', then 'b=2' * } * ``` */ entries(): IterableIterator<[K, V]>; /** * Implements the iterable protocol, allowing the map to be used with for...of loops * * @returns An iterator containing [key, value] pairs * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * for (const [key, value] of map) { * console.log(`${key}=${value}`); // Logs: 'a=1', then 'b=2' * } * ``` */ [Symbol.iterator](): IterableIterator<[K, V]>; /** * Customizes the string tag for the ImmutableMap instance * Used in Object.prototype.toString.call(immutableMap) * * @example * ```typescript * const map = new ImmutableMap(); * console.log(Object.prototype.toString.call(map)); // '[object ImmutableMap]' * ``` */ get [Symbol.toStringTag](): string; /** * Internal helper method for creating new instances when performing * mutations. This ensures immutability while allowing reuse of logic. * * @param fn - Function that performs the mutation on the cloned map * @returns A new ImmutableMap instance with the mutation applied * @private */ private mutate; } /** * An immutable variant of the native `Set` class where all mutating operations * return new instances instead of modifying the original set. * * @template T - The type of elements in the set * * @example * ```typescript * const set1 = new ImmutableSet(['a', 'b']); * const set2 = set1.add('c'); * * console.log([...set1]); // ['a', 'b'] * console.log([...set2]); // ['a', 'b', 'c'] * ``` */ declare class ImmutableSet<T> { /** * Internal Set instance used for storage * @private */ private readonly set; /** * A shared empty immutable set instance. Using `never` type ensures * it can be safely cast to ImmutableSet<T> for any T. * * @example * ```typescript * const emptyStrings = ImmutableSet.Empty as ImmutableSet<string>; * const emptyNumbers = ImmutableSet.Empty as ImmutableSet<number>; * ``` * * You can also use this */ static readonly Empty: ImmutableSet<never>; /** * Creates a new ImmutableSet instance, optionally from an iterable * * This is perfect for usage with `useState` as React calls the `.from()` function * when initializing the state, but TypeScript lets us set the generic type * inline. * * ```typescript * const [set, setState] = useState(ImmutableSet.from<string>); * ``` * * @param iterable - Optional iterable of initial values * @returns A new ImmutableSet instance */ static from: <T_1>(iterable?: Iterable<T_1>) => ImmutableSet<T_1>; /** * Creates a new ImmutableSet instance * * @param iterable - Optional iterable of initial values * * @example * ```typescript * const set1 = new ImmutableSet(['a', 'b', 'c']); * const set2 = new ImmutableSet(new Set([1, 2, 3])); * const empty = new ImmutableSet<string>(); * ``` */ constructor(iterable?: Iterable<T>); /** * Internal helper method for creating new instances when performing * mutations. This ensures immutability while allowing reuse of logic. * * @param fn - Function that performs the mutation on the cloned set * @returns A new ImmutableSet instance with the mutation applied * @private */ private mutate; /** * Creates a new set with the specified value added * * @param value - The value to add * @returns A new ImmutableSet containing the added value * * @example * ```typescript * const set1 = new ImmutableSet(['a', 'b']); * const set2 = set1.add('c'); * console.log([...set2]); // ['a', 'b', 'c'] * console.log(set1 === set2); // false * ``` */ add(value: T): ImmutableSet<T>; /** * Creates a new empty set, discarding all current values * * @returns The empty ImmutableSet singleton instance * * @example * ```typescript * const set1 = new ImmutableSet(['a', 'b']); * const set2 = set1.clear(); * console.log(set2.size); // 0 * console.log(set2 === ImmutableSet.Empty); // true * ``` */ clear(): ImmutableSet<never>; /** * Creates a new set with the specified value removed * * @param value - The value to remove * @returns A new ImmutableSet with the value removed * * @example * ```typescript * const set1 = new ImmutableSet(['a', 'b', 'c']); * const set2 = set1.delete('b'); * console.log([...set2]); // ['a', 'c'] * console.log(set1.has('b')); // true * ``` */ delete(value: T): ImmutableSet<T>; /** * Executes a callback for each value in the set * * @param callbackfn - Function to execute for each value * @param thisArg - Value to use as `this` when executing the callback * * @example * ```typescript * const set = new ImmutableSet(['a', 'b', 'c']); * const results: string[] = []; * set.forEach(value => results.push(value.toUpperCase())); * console.log(results); // ['A', 'B', 'C'] * ``` */ forEach(callbackfn: (value: T, value2: T) => void, thisArg?: unknown): void; /** * Toggles a value in the set, adding it if it doesn't exist or removing it if it does * * @param value - The value to toggle * @returns A new ImmutableSet with the value toggled * * @example * ```typescript * const set = new ImmutableSet(['a', 'b']); * const set2 = set.toggle('c'); * console.log([...set2]); // ['a', 'b', 'c'] * ``` * * This is super helpful with React state management because the methods return a new instance * and it means React knows the state has changed. * * ```tsx * const [state, setState] = useState(ImmutableSet.from<string>) * <button onClick={() => setState(old => old.toggle('c'))}>Toggle c</button> * ``` */ toggle(value: T): ImmutableSet<T>; /** * Checks if a value exists in the set * * @param value - The value to check * @returns `true` if the value exists, `false` otherwise * * @example * ```typescript * const set = new ImmutableSet(['a', 'b']); * console.log(set.has('a')); // true * console.log(set.has('c')); // false * ``` */ has(value: T): boolean; /** * Returns an iterator of [value, value] pairs * * @returns An iterator containing pairs of values * * @example * ```typescript * const set = new ImmutableSet(['a', 'b']); * for (const [value1, value2] of set.entries()) { * console.log(value1 === value2); // true * } * ``` */ entries(): SetIterator<[T, T]>; /** * Returns an iterator of values (identical to values()) * * @returns An iterator containing the values * * @example * ```typescript * const set = new ImmutableSet(['a', 'b']); * const keys = [...set.keys()]; * console.log(keys); // ['a', 'b'] * ``` */ keys(): SetIterator<T>; /** * Returns an iterator of values * * @returns An iterator containing the values * * @example * ```typescript * const set = new ImmutableSet(['a', 'b']); * const values = [...set.values()]; * console.log(values); // ['a', 'b'] * ``` */ values(): SetIterator<T>; /** * Implements the iterable protocol, allowing the set to be used with for...of loops * * @returns An iterator containing the values * * @example * ```typescript * const set = new ImmutableSet(['a', 'b']); * for (const value of set) { * console.log(value); // 'a', then 'b' * } * ``` */ [Symbol.iterator](): SetIterator<T>; /** * Customizes the string tag for the ImmutableSet instance * Used in Object.prototype.toString.call(immutableSet) * * @example * ```typescript * const set = new ImmutableSet(); * console.log(Object.prototype.toString.call(set)); // '[object ImmutableSet]' * ``` */ get [Symbol.toStringTag](): string; /** * Returns the number of values in the set * * @example * ```typescript * const set = new ImmutableSet(['a', 'b']); * console.log(set.size); // 2 * ``` */ get size(): number; } /** * A strict variant of the native `Map` class that enforces explicit handling of missing keys. * Unlike the standard Map, this implementation requires specifying default value behavior * when accessing potentially missing keys. * * @template K - The key type * @template V - The value type * * @example * ```typescript * const map = new StrictMap<string, number>(); * * // Inserting a value if it doesn't exist * const value = map.getOr('key', () => 42); // 42 * * // Subsequent access returns the stored value * const sameValue = map.getOr('key', () => 100); // 42 * * // Using getElse for optional access * const optional = map.getElse('missing', () => null); // null * ``` */ declare class StrictMap<K, V> { /** * Internal Map instance used for storage * @private */ private readonly map; /** * Returns the number of key/value pairs in the StrictMap */ get size(): number; /** * Customizes the string tag for the StrictMap instance * Used in Object.prototype.toString.call(strictMap) */ get [Symbol.toStringTag](): string; /** * Removes all key/value pairs from the StrictMap */ clear(): void; /** * Removes the specified key and its associated value * @param key - The key to remove * @returns `true` if the key existed and was removed, `false` otherwise */ delete(key: K): boolean; /** * Executes the provided callback for each key/value pair * @param callbackfn - Function to execute for each entry * @param thisArg - Value to use as `this` when executing the callback */ forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void; /** * Retrieves the value for a key, or inserts and returns a new value if the key doesn't exist. * This is the primary method for accessing values, as it ensures all keys have an associated value. * * @param key - The key to lookup * @param or - Factory function that produces the default value if the key doesn't exist * @returns The existing value or the newly inserted default value * * @example * ```typescript * const map = new StrictMap<string, string[]>(); * const value = map.getOr('users', () => []); // Creates new array if 'users' doesn't exist * value.push('user1'); // Safe to use, we know it's an array * ``` */ getOr(key: K, or: () => V): V; /** * Similar to `getOr`, but allows returning a different type when the key doesn't exist. * This is useful for optional access patterns where you don't want to insert a default value. * * @param key - The key to lookup * @param or - Factory function that produces the alternative value if the key doesn't exist * @returns The existing value of type V, or the alternative value of type N * * @example * ```typescript * const map = new StrictMap<string, number>(); * const value = map.getElse('count', () => null); // Returns null if key doesn't exist * ``` */ getElse<N>(key: K, or: () => N): V | N; /** * Checks if the specified key exists * @param key - The key to check * @returns `true` if the key exists, `false` otherwise */ has(key: K): boolean; /** * Sets a key/value pair in the map * @param key - The key to set * @param value - The value to associate with the key * @returns The StrictMap instance for method chaining */ set(key: K, value: V): this; /** * Returns an iterator of key/value pairs * @returns An iterator containing [key, value] pairs */ entries(): IterableIterator<[K, V]>; /** * Returns an iterator of keys * @returns An iterator containing the keys */ keys(): IterableIterator<K>; /** * Returns an iterator of values * @returns An iterator containing the values */ values(): IterableIterator<V>; /** * Implements the iterable protocol, allowing the StrictMap to be used with for...of loops * @returns An iterator containing [key, value] pairs */ [Symbol.iterator](): IterableIterator<[K, V]>; } export { ImmutableMap, ImmutableSet, StrictMap };