0Z4C0
// navigation
// @ozaco/std

Result

Typed success/failure values and optional values without exceptions.

import from@ozaco/std/result

A Result<T, E> is either a Success<T> carrying a value or a Failure<E> carrying an error, message and a list of causes. A Maybe<T> models presence (Just) or absence (Nothing).

Every constructor transparently handles promises: pass a PromiseLike and you get back a Result.Async<T, E> (a Promise<Result<T, E>>), so the same helpers work for sync and async code.

Both Result and Maybe are plain objects tagged with a registered Symbol, and Result is iterable — enabling generator-style yield* unwrapping.

01

Constructors

Build results and optional values.

fn

succeed

Wrap a value in a `Success`. Awaits promises into a `Result.Async`.

signature
function succeed(): Result<void, never>
function succeed<const T>(value: T): Result.For<T, Awaited<T>, never>
// parameters
value?: T
The success value. If a promise, the result becomes async.
// returns A `Result.Success<T>`, or `Result.Async` when `value` is a promise.
example
import { succeed } from '@ozaco/std/result'

const ok = succeed(42) //=> Success<number>
const unit = succeed() //=> Success<void>
const later = succeed(fetchUser()) //=> Result.Async<User, never>
fn

fail

Wrap an error in a `Failure`, optionally with a message and causes.

signature
function fail(): Result<never, void>
function fail<const E>(
  error: E,
  message?: string,
  ...causes: string[]
): Result.For<E, never, Awaited<E>>
// parameters
error?: E
The error value.
message?: string
Human-readable message stored on the failure.
causes?: string[]
Chain of upstream cause descriptions.
// returns A `Result.Failure<E>`, or `Result.Async` when `error` is a promise.
example
import { fail } from '@ozaco/std/result'

const err = fail(new Error('boom'), 'while parsing', 'config.load')
//=> Failure<Error> { message: 'while parsing', causes: ['config.load'] }
fn

just

Wrap a value in a `Maybe.Just`.

signature
function just(): Maybe<void>
function just<T>(value?: T): Maybe<T>
// returns A `Maybe.Just<T>`.
example
import { just } from '@ozaco/std/result'

const present = just('token') //=> Just<string>
fn

nothing

Create an empty `Maybe.Nothing`.

signature
function nothing<T = void>(): Maybe<T>
// returns A `Maybe.Nothing<T>`.
example
import { nothing } from '@ozaco/std/result'

const absent = nothing<string>() //=> Nothing<string>
02

Guards

Narrow unknown values with type predicates.

fn

isSuccess

Narrow a value to `Result.Success`.

signature
function isSuccess(value: unknown): value is Result.Success<unknown>
fn

isFailure

Narrow a value to `Result.Failure`.

signature
function isFailure(value: unknown): value is Result.Failure<unknown>
fn

isResult

Narrow a value to any `Result`.

signature
function isResult(value: unknown): value is Result<unknown, unknown>
fn

isJust

Narrow a value to `Maybe.Just`.

signature
function isJust(value: unknown): value is Maybe.Just<unknown>
fn

isNothing

Narrow a value to `Maybe.Nothing`.

signature
function isNothing(value: unknown): value is Maybe.Nothing<unknown>
fn

isMaybe

Narrow a value to any `Maybe`.

signature
function isMaybe(value: unknown): value is Maybe<unknown>
03

Combinators

Normalize, unwrap and adapt results.

fn

auto

Coerce any value into a `Result`, passing existing results through.

signature
function auto<R extends Result.Both<any, any>>(result: R): /* normalized */ Result<...>
function auto<R extends Result.Both<any, any>, T>(result: R, defaultValue: T): Result<...>
function auto<const T>(value: T): Result.ResultFromUnion<T>

Existing results are returned untouched; plain values are wrapped in succeed. When a defaultValue is given, a failure is replaced by auto(defaultValue). Promises resolve first, yielding a Result.Async.

// returns A `Result` (or `Result.Async`) inferred from the input.
example
import { auto } from '@ozaco/std/result'

auto(42)                //=> Success<number>
auto(someResult)        //=> someResult, unchanged
auto(mightFail, 'fallback') //=> Success<'fallback'> if it failed
fn

unwrap

Extract the success value, or throw / return a default on failure.

signature
function unwrap<R extends Result.Both<any, any>>(result: R): Result.InferSuccess<R>
function unwrap<R extends Result.Both<any, any>, T>(
  result: R,
  defaultValue: T,
): Result.InferSuccess<R> | T

Without a default, a failure is thrown (the Failure object itself). With a default, the default is returned instead. Async results unwrap to a Promise.

// returns The success value, the `defaultValue`, or throws.
example
import { succeed, fail, unwrap } from '@ozaco/std/result'

unwrap(succeed(42))          //=> 42
unwrap(fail('x'), 0)         //=> 0
unwrap(fail('x'))            //   throws the Failure
fn

throwable

Run a callback and capture thrown errors as a `Failure`.

signature
function throwable<R, E extends Result.ErrorConstructor>(
  cb: () => R,
  errorClass?: E,
  ...causes: string[]
): Result.ResultFromUnion<R | Result.Failure<E['prototype']>>

Wraps cb in a try/catch. A thrown value is normalized into fail(...); if errorClass is provided and the thrown value is not an instance of it, it is wrapped via new errorClass(error). Async callbacks are handled too.

example
import { throwable } from '@ozaco/std/result'

const parsed = throwable(() => JSON.parse(input))
//=> Success<unknown> | Failure<Error>
fn

asFailure

Coerce any error into a `Failure`, optionally appending a cause.

signature
function asFailure<E>(error: Result.Failure<E>, cause?: string): Result.Failure<E>
function asFailure(error: unknown, cause?: string): Result.Failure<unknown>
// returns A `Result.Failure`, reusing the input if it already is one.
fn

appendCauses

Push extra cause strings onto a failure, leaving successes untouched.

signature
function appendCauses<T extends Result.Both<any, any>>(
  result: T,
  ...causes: string[]
): T
04

Types

type

Result

A success or failure value: `Result.Success<T> | Result.Failure<E>`.

signature
type Result<T, E> = Result.Success<T> | Result.Failure<E>

The Result namespace also exposes:

  • Success<T>{ value: T }, iterable, yielding the value.
  • Failure<E>{ error: E, message: string, causes: string[] }, iterable.
  • Async<T, E>Promise<Result<T, E>>.
  • Both<T, E>Result.Async<T, E> | Result<T, E>.
  • InferSuccess<T> / InferFailure<T> — extract the value/error type from a result or a function returning one.
type

Maybe

An optional value: `Maybe.Just<T> | Maybe.Nothing<T>`.

signature
type Maybe<T> = Maybe.Just<T> | Maybe.Nothing<T>

Maybe.Just<T> is { value: T }; Maybe.Nothing<T> carries no value. Both are tagged with the corresponding registered symbol.

05

Constants

Registered symbols used as discriminant tags.

const

RESULT_SUCCESS

Tag for `Result.Success`.

signature
const RESULT_SUCCESS: unique symbol // Symbol.for('std:result:success')
const

RESULT_FAILURE

Tag for `Result.Failure`.

signature
const RESULT_FAILURE: unique symbol // Symbol.for('std:result:failure')
const

MAYBE_JUST

Tag for `Maybe.Just`.

signature
const MAYBE_JUST: unique symbol // Symbol.for('std:result:just')
const

MAYBE_NOTHING

Tag for `Maybe.Nothing`.

signature
const MAYBE_NOTHING: unique symbol // Symbol.for('std:result:nothing')