UNPKG

@onrails/result

Version:

Tagged Result / ResultAsync for railway-oriented TypeScript — pure tagged unions, neverthrow-shaped compat shim, FL-friendly

56 lines (54 loc) 1.73 kB
/** * The core railway type: a tagged union carrying either a success value * (`Ok<T>`) or a failure value (`Err<E>`). It is a plain discriminated union * on `_tag` — no classes — so it is immutable and tree-shake friendly. Narrow * with {@link isOk} / {@link isErr} to read `.value` / `.error`. * * @typeParam T - the `Ok` value type * @typeParam E - the `Err` error type * * @example * ```ts * function parse(raw: string): Result<number, "nan"> { * const n = Number(raw); * return Number.isNaN(n) ? err("nan") : ok(n); * } * ``` */ type Result<T, E> = { readonly _tag: "Ok"; readonly value: T; } | { readonly _tag: "Err"; readonly error: E; }; /** * The success branch of a {@link Result} — `{ _tag: "Ok"; value: T }`. * The `E` parameter keeps the type assignable to `Result<T, E>`. */ type Ok<T, E = never> = Extract<Result<T, E>, { _tag: "Ok"; }>; /** * The failure branch of a {@link Result} — `{ _tag: "Err"; error: E }`. */ type Err<T, E> = Extract<Result<T, E>, { _tag: "Err"; }>; /** * Error subclass representing an **unexpected** defect — a thrown exception or * promise rejection that was not part of the modelled `Err` union. Used as the * default mapping when {@link fromAsync} is called without an `onDefect` * handler; the original cause is preserved on `.cause`. * * @example * ```ts * const defect = new UnexpectedError("Unexpected async defect", caught); * defect.cause; // the original thrown value * ``` */ declare class UnexpectedError extends Error { readonly cause?: unknown | undefined; constructor(message: string, cause?: unknown | undefined); } export { type Err as E, type Ok as O, type Result as R, UnexpectedError as U };