@conjecture-dev/g-std
Version:
A collection of TypeScript utility functions for common programming tasks
210 lines (209 loc) • 8.11 kB
TypeScript
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;