Typed Result for Error Handling

Model success and failure as a discriminated Result type instead of throwing, forcing callers to handle the error branch explicitly at compile time.

TypescriptResilience

Code

snippet
export type Result<T, E = Error> =
  | { ok: true; value: T }
  | { ok: false; error: E };

export function ok<T>(value: T): Result<T, never> {
  return { ok: true, value };
}

export function fail<E>(error: E): Result<never, E> {
  return { ok: false, error };
}

export function unwrapOr<T, E>(result: Result<T, E>, fallback: T): T {
  return result.ok ? result.value : fallback;
}

export async function tryCatch<T>(fn: () => Promise<T>): Promise<Result<T>> {
  try {
    return ok(await fn());
  } catch (error) {
    return fail(error instanceof Error ? error : new Error(String(error)));
  }
}