/** * Toolkit - Type Helpers * * TypeScript utility types and helper functions. */ /** * Make specific properties optional */ export type PartialBy = Omit & Partial>; /** * Make specific properties required */ export type RequiredBy = Omit & Required>; /** * Deep partial (makes all nested properties optional) */ export type DeepPartial = T extends object ? { [P in keyof T]?: DeepPartial } : T; /** * Extract keys of a certain type */ export type KeysOfType = { [K in keyof T]: T[K] extends U ? K : never; }[keyof T]; /** * Ensure all keys of a type are present */ export function ensureKeys>( obj: Partial, keys: (keyof T)[] ): obj is T { return keys.every(key => key in obj); } /** * Pick properties by value type */ export type PickByValue = Pick< T, { [K in keyof T]: T[K] extends V ? K : never; }[keyof T] >; /** * Safely access nested property */ export function getNestedProperty(obj: unknown, path: string, defaultValue?: T): T | undefined { const keys = path.split("."); let current: unknown = obj; const isIndexableObject = (value: unknown): value is Record => typeof value === "object" && value !== null; for (const key of keys) { if (!isIndexableObject(current)) { return defaultValue; } current = current[key]; } if (current === undefined || current === null) { return defaultValue; } return current as T; } // ============================================================================ // Async State Management // ============================================================================ /** * Generic async state type for handling loading/success/error states */ export type AsyncState = | { status: "idle" } | { status: "loading" } | { status: "success"; data: T } | { status: "error"; error: E }; /** * Create an idle state */ export function createIdleState(): AsyncState { return { status: "idle" }; } /** * Create a loading state */ export function createLoadingState(): AsyncState { return { status: "loading" }; } /** * Create a success state with data */ export function createSuccessState(data: T): AsyncState { return { status: "success", data }; } /** * Create an error state */ export function createErrorState(error: E): AsyncState { return { status: "error", error }; } /** * Type guard: check if state is idle */ export function isIdle(state: AsyncState): state is { status: "idle" } { return state.status === "idle"; } /** * Type guard: check if state is loading */ export function isLoading(state: AsyncState): state is { status: "loading" } { return state.status === "loading"; } /** * Type guard: check if state is success */ export function isSuccess(state: AsyncState): state is { status: "success"; data: T } { return state.status === "success"; } /** * Type guard: check if state is error */ export function isError(state: AsyncState): state is { status: "error"; error: E } { return state.status === "error"; }