Skip to main content Link Search Menu Expand Document (external link)

OptionX overview

Generic, framework-agnostic extensions to Effect’s Option module.

Added in v0.0.0


Table of contents


combinators

tupleOf

Combines two Options into an Option of a tuple, succeeding only when both are Some.

Returns Some([a, b]) when both inputs are Some, and None if either is None. Useful when an operation needs two optional values present at once.

Signature

export declare const tupleOf: (<B>(b: Option.Option<B>) => <A>(a: Option.Option<A>) => Option.Option<[A, B]>) &
  (<A, B>(a: Option.Option<A>, b: Option.Option<B>) => Option.Option<[A, B]>)

Example

import { Option, pipe } from "effect"
import { OptionX } from "@nunofyobiz/effect-extras"

// Both Some — succeeds with the pair
assert.deepStrictEqual(OptionX.tupleOf(Option.some(1), Option.some("a")), Option.some([1, "a"]))

// Either None collapses to None
assert.deepStrictEqual(OptionX.tupleOf(Option.some(1), Option.none()), Option.none())

// Data-last (piped): the piped Option fills the first tuple slot
assert.deepStrictEqual(pipe(Option.some(1), OptionX.tupleOf(Option.some("a"))), Option.some([1, "a"]))

Added in v0.0.0

constructors

fromNullableOption

Normalizes a possibly-nullish Option into a plain Option, mapping null and undefined to None.

Handy at boundaries where an Option value might itself arrive as null or undefined (for example an optional field that holds an Option): the result is always a well-formed Option, never null/undefined.

Signature

export declare const fromNullableOption: <A>(nullableOption: Option.Option<A> | null | undefined) => Option.Option<A>

Example

import { Option } from "effect"
import { OptionX } from "@nunofyobiz/effect-extras"

assert.deepStrictEqual(OptionX.fromNullableOption(Option.some(1)), Option.some(1))
assert.deepStrictEqual(OptionX.fromNullableOption(null), Option.none())
assert.deepStrictEqual(OptionX.fromNullableOption(undefined), Option.none())

Added in v0.0.0

mapping

mapSomeOrNull

Maps the value of an Option when it is Some, returning null when it is None.

A shorthand for pipe(self, Option.map(map), Option.getOrNull). The null fallback makes it especially convenient in JSX/React, where rendering null skips output — mapSomeOrNull(value, (v) => render(v)) replaces a more verbose Option.match with onNone: () => null.

Signature

export declare const mapSomeOrNull: (<A, B>(map: (a: A) => B) => (self: Option.Option<A>) => B | null) &
  (<A, B>(self: Option.Option<A>, map: (a: A) => B) => B | null)

Example

import { Option, pipe } from "effect"
import { OptionX } from "@nunofyobiz/effect-extras"

// data-first
assert.deepStrictEqual(
  OptionX.mapSomeOrNull(Option.some(1), (v) => v + 1),
  2
)

// None maps to null
assert.deepStrictEqual(
  OptionX.mapSomeOrNull(Option.none<number>(), (v) => v + 1),
  null
)

// data-last (piped)
assert.deepStrictEqual(
  pipe(
    Option.some(1),
    OptionX.mapSomeOrNull((v) => v + 1)
  ),
  2
)

Added in v0.0.0

mapSomeOrUndefined

Maps the value of an Option when it is Some, returning undefined when it is None.

The undefined-returning counterpart of {@link mapSomeOrNull}: a shorthand for pipe(self, Option.map(map), Option.getOrUndefined). Reach for it when the consuming API expects undefined rather than null for “absent” (for example an optional prop or a value spread into an object).

Signature

export declare const mapSomeOrUndefined: (<A, B>(map: (a: A) => B) => (self: Option.Option<A>) => B | undefined) &
  (<A, B>(self: Option.Option<A>, map: (a: A) => B) => B | undefined)

Example

import { Option, pipe } from "effect"
import { OptionX } from "@nunofyobiz/effect-extras"

// data-first
assert.deepStrictEqual(
  OptionX.mapSomeOrUndefined(Option.some(1), (v) => v + 1),
  2
)

// None maps to undefined
assert.deepStrictEqual(
  OptionX.mapSomeOrUndefined(Option.none<number>(), (v) => v + 1),
  undefined
)

// data-last (piped)
assert.deepStrictEqual(
  pipe(
    Option.some(1),
    OptionX.mapSomeOrUndefined((v) => v + 1)
  ),
  2
)

Added in v0.0.0

sequencing

ifSome

Runs a side effect with the value of an Option when it is Some, doing nothing when it is None.

A shorthand for the “if Some, do something” branch of Option.match where the None case is a no-op. The callback’s return value is ignored — ifSome always returns void.

Signature

export declare const ifSome: (<A>(ifSome: (value: A) => void) => (self: Option.Option<A>) => void) &
  (<A>(self: Option.Option<A>, ifSome: (value: A) => void) => void)

Example

import { Option } from "effect"
import { OptionX } from "@nunofyobiz/effect-extras"

const log: Array<number> = []
OptionX.ifSome(Option.some(1), (value) => log.push(value))
OptionX.ifSome(Option.none<number>(), (value) => log.push(value))

assert.deepStrictEqual(log, [1])

Added in v0.0.0

inspectSome

Runs a side effect with the value of an Option when it is Some, then returns the Option unchanged.

The pass-through counterpart of {@link ifSome}: it taps into a Some value (for logging, metrics, debugging) without breaking a pipe chain, since it returns the original Option. For None it is a no-op.

Signature

export declare const inspectSome: (<A>(function_: (value: A) => void) => (self: Option.Option<A>) => Option.Option<A>) &
  (<A>(self: Option.Option<A>, function_: (value: A) => void) => Option.Option<A>)

Example

import { Option, pipe } from "effect"
import { OptionX } from "@nunofyobiz/effect-extras"

const log: Array<number> = []
const result = pipe(
  Option.some(1),
  OptionX.inspectSome((value) => log.push(value)),
  Option.map((value) => value + 1)
)

assert.deepStrictEqual(result, Option.some(2))
assert.deepStrictEqual(log, [1])

Added in v0.0.0