/** * @file Unified Type Utilities * @description Centralized type guards, type utilities, and type narrowing functions. * * This module consolidates type guards from: * - utils/guardUtils.ts * - Various inline implementations across the codebase * * @module shared/type-utils */ /** * Check if value is defined (not null or undefined). * * @example * ```ts * const items = [1, null, 2, undefined, 3]; * const defined = items.filter(isDefined); // [1, 2, 3] * ``` */ export declare function isDefined(value: T | null | undefined): value is T; /** * Check if value is null or undefined. */ export declare function isNullish(value: unknown): value is null | undefined; /** * Check if value is a string. */ export declare function isString(value: unknown): value is string; /** * Check if value is a non-empty string (after trimming whitespace). */ export declare function isNonEmptyString(value: unknown): value is string; /** * Check if value is a number (not NaN). */ export declare function isNumber(value: unknown): value is number; /** * Check if value is a finite number. */ export declare function isFiniteNumber(value: unknown): value is number; /** * Check if value is a positive number. */ export declare function isPositiveNumber(value: unknown): value is number; /** * Check if value is a non-negative number (>= 0). */ export declare function isNonNegativeNumber(value: unknown): value is number; /** * Check if value is an integer. */ export declare function isInteger(value: unknown): value is number; /** * Check if value is a boolean. */ export declare function isBoolean(value: unknown): value is boolean; /** * Check if value is a symbol. */ export declare function isSymbol(value: unknown): value is symbol; /** * Check if value is a bigint. */ export declare function isBigInt(value: unknown): value is bigint; /** * Check if value is a function. */ export declare function isFunction(value: unknown): value is (...args: unknown[]) => unknown; /** * Check if value is a plain object (not null, not array). * * @example * ```ts * isObject({}) // true * isObject([]) // false * isObject(null) // false * ``` */ export declare function isObject(value: unknown): value is Record; /** * Check if value is a plain object (stricter - checks prototype). */ export declare function isPlainObject(value: unknown): value is Record; /** * Check if value is an array. */ export declare function isArray(value: unknown): value is T[]; /** * Check if value is a non-empty array. */ export declare function isNonEmptyArray(value: unknown): value is [T, ...T[]]; /** * Check if value is an array of a specific type. * * @example * ```ts * const maybeStrings: unknown = ['a', 'b', 'c']; * if (isArrayOf(maybeStrings, isString)) { * // maybeStrings is string[] * } * ``` */ export declare function isArrayOf(value: unknown, guard: (item: unknown) => item is T): value is T[]; /** * Check if value is a Date object (and valid). */ export declare function isDate(value: unknown): value is Date; /** * Check if value is a valid date string. */ export declare function isDateString(value: unknown): value is string; /** * Check if value is a Promise. */ export declare function isPromise(value: unknown): value is Promise; /** * Check if value is an Error. */ export declare function isError(value: unknown): value is Error; /** * Check if value is a RegExp. */ export declare function isRegExp(value: unknown): value is RegExp; /** * Check if value is a Map. */ export declare function isMap(value: unknown): value is Map; /** * Check if value is a Set. */ export declare function isSet(value: unknown): value is Set; /** * Check if value is a WeakMap. */ export declare function isWeakMap(value: unknown): value is WeakMap; /** * Check if value is a WeakSet. */ export declare function isWeakSet(value: unknown): value is WeakSet; /** * Check if value is a valid email address. */ export declare function isEmail(value: unknown): value is string; /** * Check if value is a valid URL. */ export declare function isUrl(value: unknown): value is string; /** * Check if value is a valid UUID (v1-v5). */ export declare function isUuid(value: unknown): value is string; /** * Check if value is a valid JSON string. */ export declare function isJsonString(value: unknown): value is string; /** * Check if value is a valid ISO date string. */ export declare function isIsoDateString(value: unknown): value is string; /** * Check if object has a specific key. * * @example * ```ts * const obj: unknown = { name: 'John' }; * if (hasKey(obj, 'name')) { * // obj.name is unknown but accessible * } * ``` */ export declare function hasKey(obj: unknown, key: K): obj is Record; /** * Check if object has all required keys. * * @example * ```ts * const obj: unknown = { name: 'John', age: 30 }; * if (hasKeys(obj, ['name', 'age'])) { * // obj has both name and age * } * ``` */ export declare function hasKeys(obj: unknown, keys: readonly K[]): obj is Record; /** * Check if object has a key with a specific type. * * @example * ```ts * const obj: unknown = { count: 42 }; * if (hasTypedKey(obj, 'count', isNumber)) { * // obj.count is number * } * ``` */ export declare function hasTypedKey(obj: unknown, key: K, guard: (value: unknown) => value is T): obj is Record; /** * Assert that a value matches a type guard, throwing if it doesn't. * * @example * ```ts * function processUser(data: unknown) { * assert(data, isObject, 'Expected object'); * // data is Record * } * ``` */ export declare function assert(value: unknown, guard: (value: unknown) => value is T, message?: string): asserts value is T; /** * Check if value is one of allowed values. * * @example * ```ts * const status: unknown = 'active'; * if (isOneOf(status, ['active', 'inactive', 'pending'] as const)) { * // status is 'active' | 'inactive' | 'pending' * } * ``` */ export declare function isOneOf(value: unknown, allowedValues: readonly T[]): value is T; /** * Narrow type or return undefined. * * @example * ```ts * const maybeString = narrow(value, isString); * // maybeString is string | undefined * ``` */ export declare function narrow(value: unknown, guard: (value: unknown) => value is T): T | undefined; /** * Narrow type or return default value. * * @example * ```ts * const name = narrowOr(value, isString, 'Anonymous'); * // name is string (never undefined) * ``` */ export declare function narrowOr(value: unknown, guard: (value: unknown) => value is T, defaultValue: T): T; /** * Create a type guard for object shape. * * @example * ```ts * interface User { * name: string; * age: number; * } * * const isUser = createShapeGuard({ * name: isString, * age: isNumber, * }); * * if (isUser(data)) { * // data is User * } * ``` */ export declare function createShapeGuard>(shape: { [K in keyof T]: (value: unknown) => value is T[K]; }): (value: unknown) => value is T; /** * Create a type guard for optional object shape (allows undefined values). */ export declare function createPartialShapeGuard>(shape: { [K in keyof T]: (value: unknown) => value is T[K]; }): (value: unknown) => value is Partial; /** * Create a type guard for union types. * * @example * ```ts * const isStringOrNumber = createUnionGuard(isString, isNumber); * ``` */ export declare function createUnionGuard(...guards: { [K in keyof T]: (value: unknown) => value is T[K]; }): (value: unknown) => value is T[number]; /** * Safe JSON parse with type guard. * * @example * ```ts * const user = safeJsonParse(jsonString, isUser); * if (user) { * // user is User * } * ``` */ export declare function safeJsonParse(json: string, guard: (value: unknown) => value is T): T | undefined; /** * Safe JSON parse returning result tuple. */ export declare function safeJsonParseResult(json: string, guard: (value: unknown) => value is T): [T, null] | [null, Error]; /** * Extract keys of type T from object U */ export type KeysOfType = { [K in keyof U]: U[K] extends T ? K : never; }[keyof U]; /** * Make specific keys required */ export type RequireKeys = T & Required>; /** * Make specific keys optional */ export type OptionalKeys = Omit & Partial>; /** * Deep partial type */ export type DeepPartial = T extends object ? { [P in keyof T]?: DeepPartial; } : T; /** * Deep readonly type */ export type DeepReadonly = T extends object ? { readonly [P in keyof T]: DeepReadonly; } : T; /** * Non-nullable values of an array */ export type NonNullableArray = T extends (infer U)[] ? NonNullable[] : never; /** * Awaited type (unwrap Promise) */ export type Awaited = T extends Promise ? U : T; /** * Function return type */ export type ReturnTypeOf = T extends (...args: unknown[]) => infer R ? R : never; /** * Function parameters type */ export type ParametersOf = T extends (...args: infer P) => unknown ? P : never; /** * Unique symbol for branded types. * @internal */ export declare const __brand: unique symbol; /** * Creates a branded (nominal) type from a base type. * * Branded types provide compile-time safety by making structurally * identical types incompatible. This prevents accidental misuse of * values that represent different concepts (e.g., milliseconds vs seconds). * * @template T - The base type to brand * @template B - The brand identifier string * * @example * ```ts * type UserId = Brand; * type OrderId = Brand; * * declare function getUser(id: UserId): User; * * const userId = 'user-123' as UserId; * const orderId = 'order-456' as OrderId; * * getUser(userId); // OK * getUser(orderId); // Compile error - OrderId is not assignable to UserId * ``` */ export type Brand = T & { readonly [__brand]: B; }; /** * Time duration in milliseconds. * * Use for all timing values like timeouts, intervals, and durations. * * @example * ```ts * const timeout: Milliseconds = ms(5000); * const delay: Milliseconds = ms(100); * ``` */ export type Milliseconds = Brand; /** * Time duration in seconds. * * Use for longer durations or when interacting with APIs that expect seconds. * * @example * ```ts * const tokenLifetime: Seconds = sec(3600); // 1 hour * ``` */ export type Seconds = Brand; /** * Distance/size in pixels. * * Use for all pixel-based measurements in layouts and UI. * * @example * ```ts * const width: Pixels = px(320); * const margin: Pixels = px(16); * ``` */ export type Pixels = Brand; /** * Percentage value (typically 0-100). * * Use for ratios, progress indicators, and percentage-based calculations. * * @example * ```ts * const progress: Percentage = pct(75); * const opacity: Percentage = pct(50); * ``` */ export type Percentage = Brand; /** * Creates a Milliseconds branded value. * * @param value - The numeric value in milliseconds * @returns A branded Milliseconds value * * @example * ```ts * const timeout = ms(5000); // 5 seconds * const debounce = ms(300); * ``` */ export declare const ms: (value: number) => Milliseconds; /** * Creates a Seconds branded value. * * @param value - The numeric value in seconds * @returns A branded Seconds value * * @example * ```ts * const duration = sec(60); // 1 minute * const ttl = sec(3600); // 1 hour * ``` */ export declare const sec: (value: number) => Seconds; /** * Creates a Pixels branded value. * * @param value - The numeric value in pixels * @returns A branded Pixels value * * @example * ```ts * const width = px(320); * const padding = px(16); * ``` */ export declare const px: (value: number) => Pixels; /** * Creates a Percentage branded value. * * @param value - The numeric value as a percentage (typically 0-100) * @returns A branded Percentage value * * @example * ```ts * const complete = pct(100); * const halfway = pct(50); * ``` */ export declare const pct: (value: number) => Percentage; /** * Converts Seconds to Milliseconds. * * @param seconds - Duration in seconds * @returns Equivalent duration in milliseconds * * @example * ```ts * const timeout = secondsToMs(sec(5)); // 5000ms * ``` */ export declare const secondsToMs: (seconds: Seconds) => Milliseconds; /** * Converts Milliseconds to Seconds. * * @param milliseconds - Duration in milliseconds * @returns Equivalent duration in seconds * * @example * ```ts * const duration = msToSeconds(ms(5000)); // 5s * ``` */ export declare const msToSeconds: (milliseconds: Milliseconds) => Seconds; /** * Result type for operations that can fail. * * Provides a type-safe alternative to throwing exceptions, following the * functional programming Either pattern. Forces explicit handling of both * success and failure cases at compile time. * * @template T - The success value type * @template E - The error type (defaults to Error) * * @example * ```ts * function divide(a: number, b: number): Result { * if (b === 0) { * return err('Division by zero'); * } * return ok(a / b); * } * * const result = divide(10, 2); * if (isOk(result)) { * console.log('Result:', result.value); // 5 * } else { * console.error('Error:', result.error); * } * ``` */ export type Result = { readonly ok: true; readonly value: T; } | { readonly ok: false; readonly error: E; }; /** * Creates a successful Result containing the given value. * * @template T - The value type * @param value - The success value * @returns A successful Result containing the value * * @example * ```ts * const result = ok(42); * // result.ok === true * // result.value === 42 * ``` */ export declare function ok(value: T): Result; /** * Creates a failed Result containing the given error. * * @template E - The error type * @param error - The error value * @returns A failed Result containing the error * * @example * ```ts * const result = err(new Error('Something went wrong')); * // result.ok === false * // result.error.message === 'Something went wrong' * ``` */ export declare function err(error: E): Result; /** * Type guard to check if a Result is successful. * * @template T - The success value type * @template E - The error type * @param result - The Result to check * @returns True if the result is successful, narrowing the type * * @example * ```ts * const result: Result = await fetchUser(id); * if (isOk(result)) { * // result.value is User here * console.log(result.value.name); * } * ``` */ export declare function isOk(result: Result): result is { ok: true; value: T; }; /** * Type guard to check if a Result is a failure. * * @template T - The success value type * @template E - The error type * @param result - The Result to check * @returns True if the result is a failure, narrowing the type * * @example * ```ts * const result: Result = await fetchUser(id); * if (isErr(result)) { * // result.error is ApiError here * console.error(result.error.message); * } * ``` */ export declare function isErr(result: Result): result is { ok: false; error: E; }; /** * Maps a successful Result value using the provided function. * * If the Result is a failure, returns the failure unchanged. * * @template T - The original success type * @template U - The mapped success type * @template E - The error type * @param result - The Result to map * @param fn - The mapping function * @returns A new Result with the mapped value or the original error * * @example * ```ts * const numResult: Result = ok(5); * const strResult = mapResult(numResult, n => n.toString()); * // strResult is Result with value "5" * ``` */ export declare function mapResult(result: Result, fn: (value: T) => U): Result; /** * Maps a failed Result error using the provided function. * * If the Result is successful, returns it unchanged. * * @template T - The success type * @template E - The original error type * @template F - The mapped error type * @param result - The Result to map * @param fn - The error mapping function * @returns A new Result with the mapped error or the original value * * @example * ```ts * const result: Result = err('failed'); * const mapped = mapError(result, msg => new Error(msg)); * // mapped is Result * ``` */ export declare function mapError(result: Result, fn: (error: E) => F): Result; /** * Chains Result-returning operations. * * If the Result is successful, applies the function to the value. * If the Result is a failure, returns the failure unchanged. * * @template T - The original success type * @template U - The chained success type * @template E - The error type * @param result - The Result to chain * @param fn - The chaining function that returns a new Result * @returns The Result from the chaining function or the original error * * @example * ```ts * const parseNumber = (s: string): Result => { * const n = parseInt(s, 10); * return isNaN(n) ? err('Invalid number') : ok(n); * }; * * const double = (n: number): Result => ok(n * 2); * * const result = flatMapResult(parseNumber('5'), double); * // result is ok(10) * ``` */ export declare function flatMapResult(result: Result, fn: (value: T) => Result): Result; /** * Unwraps a Result, returning the value if successful or throwing if failed. * * @template T - The success type * @template E - The error type * @param result - The Result to unwrap * @returns The success value * @throws The error if the Result is a failure * * @example * ```ts * const result = ok(42); * const value = unwrapResult(result); // 42 * * const failed = err(new Error('oops')); * unwrapResult(failed); // throws Error('oops') * ``` */ export declare function unwrapResult(result: Result): T; /** * Unwraps a Result, returning the value if successful or a default value if failed. * * @template T - The success type * @template E - The error type * @param result - The Result to unwrap * @param defaultValue - The default value to return on failure * @returns The success value or the default value * * @example * ```ts * const success = ok(42); * unwrapOr(success, 0); // 42 * * const failed = err(new Error('oops')); * unwrapOr(failed, 0); // 0 * ``` */ export declare function unwrapOr(result: Result, defaultValue: T): T;