Skip to content

maybe

Conditionally applies a function only when the value is not null or undefined. If the value is nullish, maybe returns it unchanged. This makes maybe useful for optional normalization or validation steps where the absence of a value should short‑circuit the transformation.

maybe never mutates input and never throws. If the callback throws or returns a rejected Promise, maybe returns a rejected Promise instead of propagating the throw.

Signature

function maybe<T>(value: T): T;
function maybe<T, A>(
  value: T | null | undefined,
  fn: (value: T) => A | Promise<A>
): A | T | null | undefined | Promise<A | T | null | undefined>;

Parameters

Returns

One of:

  • The original value — if it is null or undefined.
  • The transformed value — if the callback is synchronous.
  • A Promise resolving to the transformed value — if the callback is asynchronous.
  • A Promise rejecting with an error — if the callback throws or rejects.

Behavior

  • Pure function: no side effects.
  • Never mutates input.
  • Never throws.
  • Applies the callback only when the value is not nullish.
  • If the callback returns a Promise, the pipeline becomes asynchronous.
  • If the callback throws, the pipeline becomes asynchronous and returns a rejected Promise.

Examples

maybe(user.email, normalizeEmail)

maybe(input.age, validatePositiveInteger)

await maybe(user.id, async id => fetchUser(id))

maybe(null, x => x + 1)

Notes

  • Intentionally minimal: it only checks for null and undefined.
  • Useful for optional fields, optional transformations, and conditional pipelines.
  • Works seamlessly with pipe, compose, tap, and tryOrDefault.