/** * Generic function type for type-safe function signatures. * * Enables consistent typing across utility functions and higher-order functions * where function parameters need to be strongly typed. * * @example * function memoize(fn: Func): Func * function debounce(fn: Func, ms: number): Func */ export type Func = (...args: A) => R; /** * Generic async function type for type-safe async function signatures. * * Ensures Promise return types are properly handled in utility functions * that work with async operations. * * @example * function retry(fn: AsyncFunc, attempts: number): AsyncFunc * function withTimeout(fn: AsyncFunc, ms: number): AsyncFunc */ export type AsyncFunc = (...args: A) => Promise; /** * Generic constructor type for class-based type operations. * * Enables type-safe operations on constructor functions and class factories. * * @example * function createInstance(ctor: T, ...args: any[]): InstanceType */ export type ClassType = { new: Func } /** * Extracts only non-function properties from an object type. * * Essential for serialization, data persistence, and state management where * only data properties should be included, not methods. * * @example * interface User { id: string; name: string; save(): void; delete(): void; } * type UserData = Pick>; // { id: string; name: string; } */ export type NonFunctionProps = { [K in keyof T]: T[K] extends Func | ClassType ? never : K }[keyof T]; /** * Extracts only function properties from an object type. * * Useful for creating proxies, method decorators, or when separating * behavior from data in object-oriented designs. * * @example * interface User { id: string; name: string; save(): void; delete(): void; } * type UserMethods = Pick>; // { save(): void; delete(): void; } */ export type FunctionProps = { [K in keyof T]: T[K] extends Func | ClassType ? K : never }[keyof T]; /** * Makes all properties in a nested object optional recursively. * * Critical for partial update operations, configuration merging, and * scenarios where deep object structures need incremental updates. * * @example * interface Config { api: { url: string; timeout: number; }; ui: { theme: string; }; } * function updateConfig(partial: DeepOptional): void * updateConfig({ api: { timeout: 5000 } }); // Only timeout is required */ export type DeepOptional = { [K in keyof T]?: T[K] extends object ? DeepOptional : T[K] }; /** * Makes all properties in an object nullable. * * Essential for database result types and API responses where fields * can legitimately be null due to LEFT JOINs or missing data. * * @example * interface User { id: string; email: string; profile: Profile; } * type DatabaseUser = NullableObject; // All fields can be null */ export type NullableObject = { [K in keyof T]: T[K] | null }; /** * Generates all possible dot-notation paths for an object type. * * Essential for autocomplete in configuration systems, form builders, * and any API that accepts property paths as strings. * * @example * interface User { profile: { name: string; age: number; }; tags: string[]; } * type UserPaths = PathNames; // 'profile' | 'profile.name' | 'profile.age' | 'tags' | 'tags.0' */ export type PathNames = T extends object ? { [K in keyof T]: `${Exclude}${"" | `.${ T[K] extends Set ? SetValue extends object ? `${number}` | `${number}.${PathNames}` // "set.0.subtype" : `${number}` // "set.0" : T[K] extends Map ? MapValue extends object ? MapKey extends string | number ? `${MapKey}` | `${MapKey}.${PathNames}` // "map.key.subtype" : string | `${string}.${PathNames}` // "map.string.subtype" (fallback) : MapKey extends string | number ? `${MapKey}` // "map.key" : string // "map.string" : T[K] extends any[] ? T[K] extends (infer U)[] ? U extends object ? `${number}` | `${number}.${PathNames}` : `${number}` : `${number}` : PathNames }`}` }[keyof T] : never /** * Generates only the leaf paths (final values) for an object type. * * Useful for validation systems and data mapping where you only care * about paths that lead to actual values, not intermediate objects. * * @example * interface User { profile: { name: string; age: number; }; } * type UserLeaves = PathLeaves; // 'profile.name' | 'profile.age' */ export type PathLeaves = T extends object ? { [K in keyof T]-?: ( T[K] extends undefined ? never : `${Exclude}${PathLeaves extends never ? "" : `.${PathLeaves}`}` ) }[keyof T] : never /** * Extracts the value type at a specific string path. * * Enables type-safe deep property access with compile-time validation * of both path validity and return type correctness. Supports: * - Regular object property access * - Array/tuple index access * - Map key access * - Set index access * * @example * interface User { * profile: { name: string; age: number; }; * tags: Set; * metadata: Map; * } * type UserName = PathValue; // string * type Tag = PathValue; // string * type MetaValue = PathValue; // string */ export type PathValue = P extends `${infer Key}.${infer Rest}` ? Key extends keyof T ? PathValue : T extends Map ? K extends string | number ? Key extends `${K}` ? PathValue : never : PathValue : T extends Set ? Key extends `${number}` ? PathValue : never : T extends any[] ? Key extends `${number}` ? T extends (infer U)[] ? PathValue : never : never : never : P extends keyof T ? T[P] : T extends Map ? K extends string | number ? P extends `${K}` ? V : never : V : T extends Set ? P extends `${number}` ? V : never : T extends any[] ? P extends `${number}` ? T extends (infer U)[] ? U : never : never : never; /** * Union of string and number types. * * Commonly used for object keys, array indices, and ID types that * can be either string or numeric. * * @example * function getItem(collection: Record, key: StrOrNum): T | undefined */ export type StrOrNum = string | number /** * Represents either a single item or an array of items. * * Essential for flexible APIs that accept both individual items and * collections, reducing the need for separate method overloads. * * @example * function addClass(elements: OneOrMany, className: string): void * addClass(document.body, 'active'); // single element * addClass([el1, el2], 'active'); // multiple elements */ export type OneOrMany = T | T[]; /** * Object with string keys and string values. * * Standard type for configuration objects, HTTP headers, query parameters, * and any key-value mapping that should be serializable. * * @example * function buildQueryString(params: StringProps): string * function setAttributes(element: Element, attrs: StringProps): void */ export interface StringProps { [key: string]: string }; /** * Object with string keys and boolean values. * * Perfect for feature flags, permission sets, validation results, * and any boolean configuration mapping. * * @example * function checkPermissions(user: User): BoolProps // { canRead: true, canWrite: false } * function validateForm(data: FormData): BoolProps // { emailValid: true, nameValid: false } */ export interface BoolProps { [key: string]: boolean }; /** * Represents a value that can be either synchronous or asynchronous. * * Critical for utility functions that need to handle both sync and async * operations uniformly, enabling flexible API design. * * @example * function processData(processor: () => MaybePromise): Promise * function transform(value: T, transformer: (val: T) => MaybePromise): Promise */ export type MaybePromise = T | Promise; /** * Filters out undefined from a union type. * * Essential for type narrowing operations and ensuring required values * in contexts where undefined is not acceptable. * * @example * function requireValue(value: T | undefined): NotUndefined * type RequiredFields = { [K in keyof T]: NotUndefined } */ export type NotUndefined = T extends undefined ? never : T; /** * Union of all JavaScript falsy values. * * Comprehensive type for conditional logic, validation functions, * and type guards that need to handle all falsy cases. * * @example * function isFalsy(value: unknown): value is Falsy * function removeEmpty(arr: (T | Falsy)[]): T[] */ export type Falsy = number | false | "" | bigint | null | undefined; /** * Filters out falsy values from a type. * * Enables type-safe operations on values that are guaranteed to be * truthy, eliminating the need for runtime falsy checks. * * @example * function assertTruthy(value: T): asserts value is Truthy * function compact(arr: T[]): Truthy[] */ export type Truthy = T extends Falsy ? never : T;