Skip to main content
Result<T, E> represents a value that is either a success (Ok<T>) or a failure (Err<E>). Every Result carries its error type in the signature; no implicit throw, no silent null. Both branches share the same set of chainable methods.

Creating Results

chas.ok(value)

Wraps a value in an Ok result.
T
required
The success value to wrap.
Result<T, never>
A result in the Ok state containing value.

chas.err(error)

Wraps an error in an Err result.
E
required
The error value to wrap.
Result<never, E>
A result in the Err state containing error.

chas.okAsync(value)

Wraps a value (or Promise of a value) in a ResultAsync that resolves to Ok.
T | Promise<T>
required
The success value or promise to wrap.
ResultAsync<T, never>
A ResultAsync that resolves to Ok(value).

chas.errAsync(error)

Wraps an error (or Promise of an error) in a ResultAsync that resolves to Err.
E | Promise<E>
required
The error value or promise to wrap.
ResultAsync<never, E>
A ResultAsync that resolves to Err(error).

chas.tryCatch(fn, mapErr?)

Calls a synchronous function that may throw and wraps the outcome in a Result. Returns Ok on success or Err if the function throws.
() => T
required
The synchronous function to call.
(error: unknown) => E
Maps the thrown value to your error type. When omitted, the error is typed as unknown.
Result<T, E>
Ok(returnValue) or Err(mappedError).

chas.fromPromise(promise, mapErr?)

Wraps a Promise in a ResultAsync. Resolves to Ok on fulfillment or Err on rejection.
Promise<T>
required
The promise to wrap.
(error: unknown) => E
Maps the rejection reason to your error type. When omitted, the error is typed as unknown.
ResultAsync<T, E>
A ResultAsync wrapping the promise outcome.

Instance methods

Every Result<T, E> has the following methods regardless of whether it is Ok or Err.

.isOk()

Type guard that narrows to Ok<T>.
boolean
true if the result is Ok<T>, false otherwise. When true, TypeScript narrows the type so result.value is accessible.

.isErr()

Type guard that narrows to Err<E>.
boolean
true if the result is Err<E>, false otherwise. When true, TypeScript narrows the type so result.error is accessible.

.map(fn)

Transforms the Ok value. Err passes through unchanged.
(value: T) => U
required
Function applied to the Ok value.
Result<U, E>
Ok(fn(value)) or the original Err.

.mapErr(fn)

Transforms the Err error. Ok passes through unchanged.
(error: E) => F
required
Function applied to the Err error.
Result<T, F>
The original Ok or Err(fn(error)).

.andThen(fn)

Chains another Result-returning function (flatMap / monadic bind). If Ok, calls fn with the value and returns its result. Err short-circuits.
(value: T) => Result<U, F>
required
Function that receives the Ok value and returns a new Result.
Result<U, E | F>
The result of fn, or the original Err.

.orElse(fn)

Recovers from an Err by calling fn with the error and returning its result. Ok passes through unchanged.
(error: E) => Result<T2, F>
required
Function that receives the Err error and returns a recovery Result.
Result<T | T2, F>
The original Ok, or the result of fn.

.tap(fn)

Runs a side effect when Ok. Returns the original result unchanged.
(value: T) => void
required
Side-effect function called with the Ok value.
Result<T, E>
The original result, unmodified.

.tapErr(fn)

Runs a side effect when Err. Returns the original result unchanged.
(error: E) => void
required
Side-effect function called with the Err error.
Result<T, E>
The original result, unmodified.

.match({ ok, err })

Exhaustively handles both branches and returns a value. Unlike .map, this always produces a non-Result value.
(value: T) => U
required
Handler called when the result is Ok.
(error: E) => F
required
Handler called when the result is Err.
U | F
The return value of whichever handler ran.

.unwrap()

Returns the Ok value, or throws the Err error.
T
The Ok value.
Throws the contained error if the result is Err. Prefer .unwrapOr(), .match(), or type-guarded access in production code.

.unwrapOr(defaultValue)

Returns the Ok value, or defaultValue if Err.
T2
required
Fallback value returned when the result is Err.
T | T2
The Ok value or the default.

.unwrapErr()

Returns the Err error, or throws if Ok.
E
The Err error.

.toOption()

Discards the error and converts to an Option<T>. Ok becomes Some, Err becomes None.
Option<T>
Some(value) when Ok, or None when Err.

.pipe(fn1, fn2, ...)

Passes the result through a sequence of functions. Each function receives the output of the previous one. Up to 9 functions are supported with full type inference.
(a: A) => B
required
Functions to apply in order.
B
The output of the last function.

.context(ctx)

Attaches a debug label or metadata object to the error when Err. Context entries are stored in error._context as an array, most recent first. No-op when Ok.
string | Record<string, unknown>
required
A description string or metadata object for the current step.
Result<T, E>
The same result with context prepended to error._context (if Err).

.catchTag(target, handler)

Catches a specific tagged error variant by its _tag string or error factory, calls handler with it, and removes that tag from the error union type. Unmatched tags pass through unchanged.
string | ErrorFactory
required
The _tag string to match, or an error factory created with chas.defineErrs.
(error: MatchedError) => Result<T2, E2>
required
Recovery function. Return a new Result to replace the caught error.
Result<T | T2, Exclude<E, { _tag: ... }> | E2>
A result with the matched tag removed from the error union.

.tapTag(target, handler)

Runs a side effect for a specific tagged error, leaving the result unchanged. Use this for logging or telemetry on individual error variants.
string | ErrorFactory
required
The _tag string to match, or an error factory.
(error: MatchedError) => void
required
Side-effect function called when the tag matches.
Result<T, E>
The original result, unmodified.