UNPKG

@conjecture-dev/g-std

Version:

A collection of TypeScript utility functions for common programming tasks

210 lines (209 loc) 8.11 kB
import { Outcome } from "./outcome"; export * from "./outcome"; /** * Maps over an object's entries, transforming each value while preserving keys * @param obj The source object to transform * @param fn Mapping function that receives key, value, and index * @returns New object with transformed values and same keys */ export declare function objectMap<T extends object, U>(obj: T, fn: <K extends keyof T>(key: K, value: T[K], index: number) => U): { [K in keyof T]: U; }; /** * Filters and maps an array in one pass, using an Option-like pattern * @param arr Source array to transform * @param fn Function that returns ['some', value] to keep an item or ['none'] to filter it out * @returns Array of transformed values that weren't filtered out */ export declare const arrayFilterMap: <T, U>(arr: Array<T>, fn: (x: T) => ["some", U] | ["none"]) => Array<U>; /** * Return true if the array is non-empty, and make typescript inference happy about you using myArray[0] * @param arr the array * @returns a type guard/boolean */ export declare const isNonEmpty: <T>(arr: T[]) => arr is [T, ...T[]]; /** * Recursively filters an object or array's keys at any depth * @param obj Source object or array to filter * @param fn Predicate function that returns true to keep a key, false to remove it * @returns New object with filtered keys */ export declare const deepObjectFilterK: <T>(obj: T, fn: (key: string | number | symbol) => boolean) => T; /** * Type utility that preserves nested object structures while transforming types * If T is a function, returns T unchanged * If T is an object, recursively maps over all its properties * Commonly used with Omit and other type transformations to maintain nested type information * @template T - The type to resolve */ export type Resolve<T> = T extends Function ? T : { [K in keyof T]: T[K]; }; /** * Helper function for exhaustive type checking * @param x Value that should be impossible to pass (type never) * @throws Error if called, indicating a type checking failure */ export declare const assertNever: <T = void>(x: never) => T; /** * Type utility for values that might be async */ export type MaybeAsync<T> = T | Promise<T>; /** * Checks if all items in an iterable are truthy * @param iterable Collection to check * @returns true if all items are truthy, false otherwise */ export declare const all: <T>(iterable: Iterable<T>) => boolean; /** * Creates an array of tuples containing index and value pairs * @param arr Source array * @returns Array of [index, value] tuples */ export declare const enumerate: <T>(arr: Array<T>) => Array<[number, T]>; /** * Creates a canonical string representation of a value * Sorts object keys and handles nested structures * @param value Any value to canonicalize * @returns Consistent string representation */ export declare const canonicalize: <T>(value: T) => string; /** * Finds duplicate values in an array using canonical string representation * @param arr Array to check for duplicates * @returns Array of duplicate values */ export declare const findDuplicates: <T>(arr: Array<T>) => Array<T>; /** * Template literal tag for type-safe string interpolation * @param strs Template string array * @param params Values to interpolate (must be string, number, or boolean) * @returns Interpolated string * @throws Error if any param is not a string, number, or boolean */ export declare const f: (strs: TemplateStringsArray, ...params: Array<string | number | boolean>) => string; /** * Creates an immutable (frozen) copy of an object or array * @param x Object or array to freeze * @returns Frozen copy of the input */ export declare const ice: <T extends (Record<string, any> | Array<any>)>(x: T) => T; /** * Type-safe version of Object.fromEntries * @param entries Array of key-value pairs * @returns Object constructed from entries with preserved types */ export declare const objectFromEntries: <Key extends string | number, Value, T extends Record<Key, Value>>(entries: Array<[Key, Value]>) => T; /** * Type-safe version of Object.entries * @param obj Source object * @returns Array of key-value pairs with preserved types */ export declare const objectEntries: <Key extends string | number, Value>(obj: Record<Key, Value>) => Array<[Key, Value]>; /** * Check if any item in the iterable is truthy * * @param iterable Collection to check */ export declare const any: <T>(iterable: Iterable<T>) => boolean; /** * Transposes two arrays into a single array of tuples (like python's zip) * @param a First array * @param b Second array * @returns Array of tuples * @throws Error if arrays are of different lengths */ export declare const zip: <T, U>(a: Array<T>, b: Array<U>) => Array<[T, U]>; /** * Transposes two arrays into a single array of tuples (like python's zip) in a safe way * @param a First array * @param b Second array * @returns Array of tuples if a and b have the same size. Otherwise, return the size of a and b */ export declare const zipOutcome: <T, U>(a: Array<T>, b: Array<U>) => Outcome<Array<[T, U]>, { a: number; b: number; }>; /** * Sorts an array (not in place) * @param arr Array to sort * @param compareFn Comparison function (returns -1 if a < b, 0 if a == b, 1 if a > b) * @returns Sorted array */ export declare const sorted: <T>(arr: Array<T>, compareFn?: (a: T, b: T) => number) => Array<T>; /** * Same as Promise.withResolvers, but in 2024 * @returns Object containing a promise and its resolve/reject functions */ export declare const promiseWithResolvers: <T>() => { promise: Promise<T>; resolve: (_: T) => void; reject: (_: unknown) => void; }; export type ThrounceOptions = { throunceMs: number; }; type ThrottleError = `throttled`; /** * Prevents a function from being called more than once within a specified time interval * * Rejected calls return Failure("throttled") * * @param options How many milliseconds to wait before allowing another call * @param inputFn Function to throttle * @returns Throttled function */ export declare const throuncedAsync: <I extends Array<any>, O>(inputFn: (...is: I) => MaybeAsync<O>, options: ThrounceOptions) => { fn: (...is: I) => Promise<Outcome<O, ThrottleError>>; flush: () => Promise<void> | undefined; }; /** * Class that remembers a last value and can tell if a new value is different */ export declare class ChangeDetector<T = any> { private lastValueCanonicalized; hasChanged(newValue: T): boolean; } /** * Flattens an array of arrays * @param arr Array of arrays * @returns Flattened array */ export declare const flatten: <T>(arr: Array<Array<T>>) => Array<T>; /** * Same as Array.prototype.findIndex, but returns null if the item is not found * @param arr Array to search * @param fn Function to test each element * @returns Index of the first element that satisfies the function, or null if not found */ export declare const safeFindIndex: <T>(arr: Array<T>, fn: (x: T) => boolean) => number | null; /** * Checks if all items in an array are non-null * @param arr Array to check * @returns true if all items are non-null, false otherwise */ export declare const allNonNull: <T>(arr: Array<T | null>) => arr is Array<T>; /** * Returns all consecutive subarrays of length num * @param arr Array to check * @param num Length of the subarrays * @returns All consecutive subarrays of length num */ export declare const consecutive: <T>(arr: Array<T>, num: number, options?: { padding?: boolean; default?: T; }) => Array<Array<T>>; /** * Parses a string as an integer, returning null if the string is not a valid integer * @param x String to parse * @returns Parsed integer, or null if the string is not a valid integer */ export declare const safeParseInt: (x: string) => number | null; /** * Clamps a number between a minimum and maximum value * @param x The number to clamp * @param min The minimum value * @param max The maximum value * @returns The clamped number */ export declare const clamp: (x: number, min: number, max: number) => number;