Skip to content
Zap Studio
monads
Esc
navigateopen⌘Jpreview
On this page

Option

Option<T> constructors, guards, and combinators for explicit, type-safe null handling.

Option<T> represents either a present value (Some<T>) or its absence (None). It’s an explicit alternative to null/undefined checks — absence is part of the type, and the compiler checks that both branches are handled.

import type { Option } from "@zap-studio/monads";

Constructors

import { none, some } from "@zap-studio/monads";

some(42); // { some: true, value: 42 }
none(); // { some: false }

Guards

import { isNone, isSome, none, some } from "@zap-studio/monads";

isSome(some(1)); // true
isNone(none()); // true

Bridging From Nullable Values

import { fromNullable } from "@zap-studio/monads";

fromNullable([1, 2, 3].find((n) => n > 5)); // None
fromNullable([1, 2, 3].find((n) => n > 1)); // Some(2)

Combinators

All combinators live under the Option namespace to avoid colliding with Result’s combinators of the same name, and are curried — compose them with pipe.

import { none, Option, pipe, some } from "@zap-studio/monads";

pipe(
  some(2),
  Option.map((n) => n * 2),
); // Some(4)

const half = (n: number) => (n % 2 === 0 ? some(n / 2) : none());
pipe(some(4), Option.andThen(half)); // Some(2)

pipe(
  none(),
  Option.orElse(() => some(0)),
); // Some(0)
pipe(
  some(1),
  Option.orElse(() => some(0)),
); // Some(1), fallback not called

pipe(none(), Option.unwrapOr(0)); // 0
pipe(
  none(),
  Option.unwrapOrElse(() => 99),
); // 99

pipe(some(42), Option.match({ some: (n) => `got ${n}`, none: () => "nothing" })); // "got 42"

orElse mirrors Rust’s Option::or_else: it recovers a None into a fallback Option of the same type, and leaves a Some untouched without calling the fallback.

Unwrapping

Option.unwrap throws if the Option is None, mirroring Rust’s Option::unwrap.

import { none, Option } from "@zap-studio/monads";

Option.unwrap(none()); // throws Error("Called unwrap() on a None value")

Prefer Option.match, Option.unwrapOr, or Option.unwrapOrElse for control flow that shouldn’t throw.

Last updated on September 21, 2026

Was this page helpful?