Skip to content
Effect Days 2026 Get your ticket

Option

Models a value that may be present or absent.

An Option<A> is Some<A> when a value is available and None when it is not. This lets code handle missing values explicitly instead of relying on null or undefined. The module includes helpers for creating, checking, transforming, combining, and extracting optional values, plus conversions to and from common nullable or result-like shapes. It also includes Option.gen for writing small generator-based computations that stop at the first None.

68 exports Added in v2.0.0 Source

Combining

all

Added in v2.0.0 Source

Combines a structure of Options (tuple, struct, or iterable) into a single Option containing the unwrapped structure.

When to use

Use when you need to combine multiple Option values into one while preserving the input shape, with any None making the result None.

Details

  • Tuple input → Option of a tuple with the same length
  • Struct input → Option of a struct with the same keys
  • Iterable input → Option of an Array
  • Any None in the input → entire result is None

See

Signature

declare const all: <I extends Iterable<Option<any>> | Record<string, Option<any>>>(input: I) => [I] extends [ReadonlyArray<Option<any>>] ? Option<{ [K in keyof I]: [I[K]] extends [Option<infer A>] ? A : never }> : [I] extends [Iterable<Option<infer A>>] ? Option<Array<A>> : Option<{ [K in keyof I]: [I[K]] extends [Option<infer A>] ? A : never }>

Example

(Combining a tuple and a struct)

import { Option } from "effect"
const maybeName: Option.Option<string> = Option.some("John")
const maybeAge: Option.Option<number> = Option.some(25)
// ┌─── Option<[string, number]>
// ▼
const tuple = Option.all([maybeName, maybeAge]) // => Option.some(["John", 25])
// ┌─── Option<{ name: string; age: number; }>
// ▼
const struct = Option.all({ name: maybeName, age: maybeAge }) // => Option.some({ name: "John", age: 25 })

product

Added in v2.0.0 Source

Combines two Options into a Some containing a tuple [A, B] if both are Some.

When to use

Use when you need to require two Option values to both be Some and keep both values as a tuple.

Details

  • Both SomeSome([a, b])
  • Either NoneNone

See

  • zipWith to combine with a function instead of a tuple
  • all to combine many Options

Signature

declare function product<A, B>(self: Option<A>, that: Option<B>): Option<[A, B]>

Example

(Pairing two Options)

import { Option } from "effect"
Option.product(Option.some("hello"), Option.some(42)) // => Option.some(["hello", 42])
Option.product(Option.none(), Option.some(42)) // => Option.none()

productMany

Added in v2.0.0 Source

Combines a primary Option with an iterable of Options into a tuple if all are Some.

When to use

Use when you need several Option values of the same type to all be Some and return them as a non-empty tuple.

Details

  • All SomeSome([self.value, ...rest])
  • Any NoneNone

See

  • product for combining exactly two
  • all for tuples, structs, and iterables

Signature

declare function productMany<A>(self: Option<A>, collection: Iterable<Option<A>>): Option<[A, ...Array<A>]>

Example

(Combining many Options)

import { Option } from "effect"
const first = Option.some(1)
const rest = [Option.some(2), Option.some(3)]
Option.productMany(first, rest) // => Option.some([1, 2, 3])
Option.productMany(first, [Option.some(2), Option.none()]) // => Option.none()

Constructors

Do

Added in v2.0.0 Source

Provides an Option containing an empty record {}, used as the starting point for do notation chains.

When to use

Use when you need to start an Option do notation pipeline before adding bindings.

See

  • bind to add Option values
  • let to add plain values
  • bindTo to start by naming an existing Option

Signature

declare const Do: Option<{}>

Example

(Building Option pipelines with do notation)

import { Option, pipe } from "effect"
pipe(
Option.Do,
Option.bind("x", () => Option.some(2)),
Option.bind("y", () => Option.some(3)),
Option.let("sum", ({ x, y }) => x + y),
Option.filter(({ x, y }) => x * y > 5)
) // => Option.some({ x: 2, y: 3, sum: 5 })

fromIterable

Added in v2.0.0 Source

Wraps the first element of an Iterable in a Some, or returns None if the iterable is empty.

When to use

Use when you need to safely extract the head of a collection, including generators or lazy iterables.

Details

  • Only consumes the first element; does not iterate the rest
  • Returns None for empty iterables

See

  • toArray for the inverse direction

Signature

declare function fromIterable<A>(collection: Iterable<A>): Option<A>

Example

(Getting the first element)

import { Option } from "effect"
Option.fromIterable([1, 2, 3]) // => Option.some(1)
Option.fromIterable([]) // => Option.none()

Creates a Combiner for Option<A> with fail-fast semantics: returns None if either operand is None.

When to use

Use when you need an Option combiner that returns None unless both operands are Some.

Details

  • None + anything → None
  • anything + NoneNone
  • Some(a) + Some(b)Some(combine(a, b))

See

Signature

declare function makeCombinerFailFast<A>(combiner: Combiner<A>): Combiner<Option<A>>

Example

(Fail-fast combining)

import { Number, Option } from "effect"
const combiner = Option.makeCombinerFailFast(Number.ReducerSum)
combiner.combine(Option.some(1), Option.some(2)) // => Option.some(3)
combiner.combine(Option.some(1), Option.none()) // => Option.none()

makeReducer

Added in v4.0.0 Source

Creates a Reducer for Option<A> that prioritizes the first non-None value and combines values when both are Some.

When to use

Use to build an Option reducer that falls back to the first available value when either side may be absent.

Details

  • None + NoneNone
  • Some(a) + NoneSome(a)
  • None + Some(b)Some(b)
  • Some(a) + Some(b)Some(combine(a, b))
  • Initial value is None

See

Signature

declare function makeReducer<A>(combiner: Combiner<A>): Reducer<Option<A>>

Example

(Reducing with first-wins semantics)

import { Number, Option } from "effect"
const reducer = Option.makeReducer(Number.ReducerSum)
reducer.combineAll([Option.some(1), Option.none(), Option.some(2)]) // => Option.some(3)

Creates a Reducer for Option<A> by lifting an existing Reducer with fail-fast semantics.

When to use

Use when you need to reduce Option values with fail-fast semantics, where any None aborts the entire result instead of being skipped.

Details

  • Initial value is Some(reducer.initialValue)
  • Combines only when both operands are Some
  • Any None causes the result to become None immediately

See

Signature

declare function makeReducerFailFast<A>(reducer: Reducer<A>): Reducer<Option<A>>

Example

(Fail-fast reducing)

import { Number, Option } from "effect"
const reducer = Option.makeReducerFailFast(Number.ReducerSum)
reducer.combineAll([Option.some(1), Option.some(2)]) // => Option.some(3)
reducer.combineAll([Option.some(1), Option.none()]) // => Option.none()

none

Added in v2.0.0 Source

Creates an Option representing the absence of a value.

When to use

Use to represent a missing or uninitialized value, such as returning "no result" from a function.

Details

  • Returns Option<never>, which is a subtype of Option<A> for any A
  • Always returns the same singleton instance

See

  • some for the opposite operation.

Signature

declare function none<A = never>(): Option<A>

Example

(Creating an empty Option)

import { Option } from "effect"
// ┌─── Option<never>
// ▼
const noValue = Option.none() // => Option.none()

some

Added in v2.0.0 Source

Wraps the given value into an Option to represent its presence.

When to use

Use to wrap a known present value as Option

  • Returning a successful result from a partial function

Details

  • Always returns Some<A>
  • Does not filter null or undefined; use fromNullishOr for that

See

  • none for the opposite operation.

Signature

declare const some: <A>(value: A) => Option<A>

Example

(Wrapping a value)

import { Option } from "effect"
// ┌─── Option<number>
// ▼
const value = Option.some(1) // => Option.some(1)

Converting

Converts a nullable value (null or undefined) into an Option.

When to use

Use when you need JavaScript nullish values to become absence at an API boundary while all other values, including falsy ones, remain present.

Details

  • null or undefinedNone
  • Any other value → Some (typed as NonNullable<A>)

See

Signature

declare function fromNullishOr<A>(a: A): Option<NonNullable<A>>

Example

(Converting nullable values to an Option)

import { Option } from "effect"
Option.fromNullishOr(undefined) // => Option.none()
Option.fromNullishOr(null) // => Option.none()
Option.fromNullishOr(1) // => Option.some(1)

fromNullOr

Added in v4.0.0 Source

Converts a possibly null value into an Option, leaving undefined as a valid Some.

When to use

Use when you want to treat only null as absent while preserving undefined as a meaningful value.

Details

  • nullNone
  • Any other value (including undefined) → Some

See

Signature

declare function fromNullOr<A>(a: A): Option<Exclude<A, null>>

Example

(Converting possibly null values to an Option)

import { Option } from "effect"
Option.fromNullOr(null) // => Option.none()
Option.fromNullOr(undefined) // => Option.some(undefined)
Option.fromNullOr(42) // => Option.some(42)

Converts a possibly undefined value into an Option, leaving null as a valid Some.

When to use

Use when you want to treat only undefined as absent while preserving null as a meaningful value.

Details

  • undefinedNone
  • Any other value (including null) → Some

See

Signature

declare function fromUndefinedOr<A>(a: A): Option<Exclude<A, undefined>>

Example

(Converting possibly undefined values to an Option)

import { Option } from "effect"
Option.fromUndefinedOr(undefined) // => Option.none()
Option.fromUndefinedOr(null) // => Option.some(null)
Option.fromUndefinedOr(42) // => Option.some(42)

getFailure

Added in v4.0.0 Source

Converts a Result into an Option, keeping only the failure value.

When to use

Use when you need to discard a Result success and keep only the failure value as an Option.

Details

  • Failure becomes Some with the failure value
  • Success becomes None and the success value is discarded

See

Signature

declare const getFailure: <A, E>(self: Result<A, E>) => Option<E>

Example

(Extracting the failure side)

import { Option, Result } from "effect"
Option.getFailure(Result.succeed("ok")) // => Option.none()
Option.getFailure(Result.fail("err")) // => Option.some("err")

getOrThrow

Added in v2.0.0 Source

Extracts the value from a Some, or throws a default Error for None.

When to use

Use when you need quick fail-fast unwrapping of an Option and a generic error is acceptable.

Details

  • Some → returns the inner value
  • None → throws new Error("getOrThrow called on a None")

See

Signature

declare const getOrThrow: <A>(self: Option<A>) => A

Example

(Throwing a default error)

import { Option, Result } from "effect"
Option.getOrThrow(Option.some(1)) // => 1
const failure = Result.try({
try: () => Option.getOrThrow(Option.none()),
catch: (error) => (error as Error).message
})
Result.getFailure(failure).pipe(Option.getOrElse(() => "no error")) // => "getOrThrow called on a None"

Extracts the value from a Some, or throws a custom error for None.

When to use

Use when you need fail-fast unwrapping of an Option for unexpected absence and want to provide a descriptive debugging error.

Details

  • Some → returns the inner value
  • None → throws the value returned by onNone()

See

Signature

declare const getOrThrowWith: {
(onNone: () => unknown): <A>(self: Option<A>) => A;
<A>(self: Option<A>, onNone: () => unknown): A;
}

Example

(Throwing a custom error)

import { Option, Result } from "effect"
Option.getOrThrowWith(Option.some(1), () => new Error("missing")) // => 1
const failure = Result.try({
try: () => Option.getOrThrowWith(Option.none(), () => new Error("missing")),
catch: (error) => (error as Error).message
})
Result.getFailure(failure).pipe(Option.getOrElse(() => "no error")) // => "missing"

getSuccess

Added in v4.0.0 Source

Converts a Result into an Option, keeping only the success value.

When to use

Use when you need to discard a Result failure and keep only the success value as an Option.

Details

  • Success becomes Some with the success value
  • Failure becomes None and the failure value is discarded

See

Signature

declare const getSuccess: <A, E>(self: Result<A, E>) => Option<A>

Example

(Extracting the success side)

import { Option, Result } from "effect"
Option.getSuccess(Result.succeed("ok")) // => Option.some("ok")
Option.getSuccess(Result.fail("err")) // => Option.none()

Lifts a function that may return null or undefined into one that returns an Option.

When to use

Use to wrap existing nullable-returning functions for use in Option pipelines

Details

  • Calls the original function with the given arguments
  • Wraps the result via fromNullishOr

See

Signature

declare function liftNullishOr<A extends readonly Array<unknown>, B>(f: (...a: A) => B): (...a: A) => Option<NonNullable<B>>

Example

(Lifting a parser)

import { Option } from "effect"
const parse = (s: string): number | undefined => {
const n = parseFloat(s)
return isNaN(n) ? undefined : n
}
const parseOption = Option.liftNullishOr(parse)
parseOption("1") // => Option.some(1)
parseOption("not a number") // => Option.none()

Lifts a function that may throw into one that returns an Option.

When to use

Use to wrap exception-throwing APIs (e.g. JSON.parse) for safe usage

Details

  • If the function returns normally → Some with the result
  • If the function throws → None (exception is swallowed)

See

Signature

declare function liftThrowable<A extends readonly Array<unknown>, B>(f: (...a: A) => B): (...a: A) => Option<B>

Example

(Lifting JSON.parse)

import { Option } from "effect"
const parse = Option.liftThrowable(JSON.parse)
parse("1") // => Option.some(1)
parse("") // => Option.none()

toArray

Added in v2.0.0 Source

Converts an Option into an Array.

When to use

Use when you need to pass an Option to array-based APIs or spread optional values into collections.

Details

  • Some → single-element array [value]
  • None → empty array []

See

Signature

declare function toArray<A>(self: Option<A>): Array<A>

Example

(Converting to an array)

import { Option } from "effect"
Option.toArray(Option.some(1)) // => [1]
Option.toArray(Option.none()) // => []

toRefinement

Added in v2.0.0 Source

Converts an Option-returning function into a type guard (refinement).

When to use

Use when you need to turn an Option-returning parser into a type-narrowing predicate, such as for Array.prototype.filter.

Details

  • Returns true when the original function returns Some
  • Returns false when the original function returns None
  • Narrows the input type to B on success

See

Signature

declare function toRefinement<A, B>(f: (a: A) => Option<B>): (a: A) => a is B

Example

(Converting a parser to a type guard)

import { Option } from "effect"
type MyData = string | number
const parseString = (data: MyData): Option.Option<string> =>
typeof data === "string" ? Option.some(data) : Option.none()
// ┌─── (a: MyData) => a is string
// ▼
const isString = Option.toRefinement(parseString)
isString("a") // => true
isString(1) // => false

Error Handling

firstSomeOf

Added in v2.0.0 Source

Returns the first Some found in an iterable of Options, or None if all are None.

When to use

Use when you need the first available Some value from a priority list.

Details

  • Short-circuits on the first Some
  • Returns None only when every element is None

See

  • orElse for a two-option fallback

Signature

declare function firstSomeOf<T, C extends Iterable<Option<T>, any, any> = Iterable<Option<T>, any, any>>(collection: C): [C] extends [Iterable<Option<A>, any, any>] ? Option<A> : never

Example

(Finding the first Some)

import { Option } from "effect"
Option.firstSomeOf([
Option.none(),
Option.some(1),
Option.some(2)
]) // => Option.some(1)

orElse

Added in v2.0.0 Source

Returns the fallback Option if self is None; otherwise returns self.

When to use

Use when you need a lazy fallback Option, such as when building priority chains of optional values.

Details

  • Some → returns self unchanged
  • None → evaluates and returns that()
  • that is lazily evaluated

See

  • orElseSome to wrap the fallback value in Some automatically
  • firstSomeOf to pick the first Some from a collection

Signature

declare const orElse: {
<B>(that: LazyArg<Option<B>>): <A>(self: Option<A>) => Option<B | A>;
<A, B>(self: Option<A>, that: LazyArg<Option<B>>): Option<A | B>;
}

Example

(Providing a fallback Option)

import { Option } from "effect"
Option.none().pipe(Option.orElse(() => Option.some("b"))) // => Option.some("b")
Option.some("a").pipe(Option.orElse(() => Option.some("b"))) // => Option.some("a")

orElseResult

Added in v4.0.0 Source

Returns the first available value and marks whether it came from the fallback.

When to use

Use when you need to know whether a present value came from the primary or fallback Option.

Details

  • self is SomeSome(Result.fail(value)) (value from primary)
  • self is None, that() is SomeSome(Result.succeed(value)) (value from fallback)
  • Both NoneNone

See

  • orElse for the simpler variant without source tracking

Signature

declare const orElseResult: {
<B>(that: LazyArg<Option<B>>): <A>(self: Option<A>) => Option<Result<B, A>>;
<A, B>(self: Option<A>, that: LazyArg<Option<B>>): Option<Result<B, A>>;
}

Example

(Tracking value source)

import { Option, Result } from "effect"
const fallback = () => Option.some("fallback")
Option.orElseResult(Option.some("primary"), fallback) // => Option.some(Result.fail("primary"))
Option.orElseResult(Option.none(), fallback) // => Option.some(Result.succeed("fallback"))

orElseSome

Added in v2.0.0 Source

Returns Some of the fallback value if self is None; otherwise returns self.

When to use

Use when providing a default plain value (not an Option) as fallback

Details

  • Some → returns self unchanged
  • None → calls onNone(), wraps result in Some, and returns it

See

  • orElse when the fallback is itself an Option

Signature

declare const orElseSome: {
<B>(onNone: LazyArg<B>): <A>(self: Option<A>) => Option<B | A>;
<A, B>(self: Option<A>, onNone: LazyArg<B>): Option<A | B>;
}

Example

(Providing a fallback value)

import { Option } from "effect"
Option.none().pipe(Option.orElseSome(() => "b")) // => Option.some("b")
Option.some("a").pipe(Option.orElseSome(() => "b")) // => Option.some("a")

Filtering

filter

Added in v2.0.0 Source

Filters an Option using a predicate. Returns None if the predicate is not satisfied or the input is None.

When to use

Use when you need to discard an Option's present value when it does not meet a condition, while narrowing the type via a refinement predicate.

Details

  • NoneNone
  • Some where predicate(value) is trueSome(value)
  • Some where predicate(value) is falseNone
  • Supports refinements for type narrowing

See

  • filterMap to transform and filter simultaneously
  • exists to test without filtering

Signature

declare const filter: {
<A, B>(refinement: Refinement<A, B>): (self: Option<A>) => Option<B>;
<A>(predicate: Predicate<A>): <B>(self: Option<B>) => Option<B>;
<A, B>(self: Option<A>, refinement: Refinement<A, B>): Option<B>;
<A>(self: Option<A>, predicate: Predicate<A>): Option<A>;
}

Example

(Filtering with a predicate)

import { Option } from "effect"
const removeEmpty = (input: Option.Option<string>) =>
Option.filter(input, (value) => value !== "")
removeEmpty(Option.some("hello")) // => Option.some("hello")
removeEmpty(Option.some("")) // => Option.none()
removeEmpty(Option.none()) // => Option.none()

filterMap

Added in v2.0.0 Source

Transforms and filters an Option using a Filter callback.

When to use

Use to transform an Option's present value and discard it when the Filter fails.

Details

The callback returns a Result: Result.succeed keeps and transforms the value, while Result.fail discards it.

See

  • filter for predicate-based filtering

Signature

declare const filterMap: {
<A, B, X>(f: Filter<A, B, X>): (self: Option<A>) => Option<B>;
<A, B, X>(self: Option<A>, f: Filter<A, B, X>): Option<B>;
}

Example

(Filtering and transforming)

import { Option, Result } from "effect"
Option.filterMap(
Option.some(2),
(n) => (n % 2 === 0 ? Result.succeed(`Even: ${n}`) : Result.failVoid)
) // => Option.some("Even: 2")

partitionMap

Added in v2.0.0 Source

Splits an Option into two Options using a function that returns a Result.

When to use

Use when you need to split an optional value into "left" and "right" channels using a Result-returning function.

Details

  • None[None, None]
  • Some where f returns Err[Some(error), None]
  • Some where f returns Ok[None, Some(value)]

See

  • filter for simple predicate-based filtering

Signature

declare const partitionMap: {
<A, B, C>(f: (a: A) => Result<C, B>): (self: Option<A>) => [left: Option<B>, right: Option<C>];
<A, B, C>(self: Option<A>, f: (a: A) => Result<C, B>): [left: Option<B>, right: Option<C>];
}

Example

(Partitioning by Result)

import { Option, Result } from "effect"
const parseNumber = (s: string): Result.Result<number, string> => {
const n = Number(s)
return isNaN(n) ? Result.fail("Not a number") : Result.succeed(n)
}
Option.partitionMap(Option.some("42"), parseNumber) // => [Option.none(), Option.some(42)]
Option.partitionMap(Option.some("abc"), parseNumber) // => [Option.some("Not a number"), Option.none()]
Option.partitionMap(Option.none(), parseNumber) // => [Option.none(), Option.none()]

Folding

Reduces an iterable of Options to a single value, skipping None entries.

When to use

Use when you need to aggregate values from a collection where some may be absent.

Details

  • Iterates through the collection, applying f only to Some values
  • None values are skipped entirely
  • Returns the accumulated result

Signature

declare const reduceCompact: {
<B, A>(b: B, f: (b: B, a: A) => B): (self: Iterable<Option<A>>) => B;
<A, B>(self: Iterable<Option<A>>, b: B, f: (b: B, a: A) => B): B;
}

Example

(Summing present values)

import { Option, pipe } from "effect"
const items = [Option.some(1), Option.none(), Option.some(2), Option.none()]
pipe(items, Option.reduceCompact(0, (b, a) => b + a)) // => 3

Generators

gen

Added in v2.0.0 Source

Provides generator-based syntax for Option, similar to async/await but for optional values. Yielding a None short-circuits the generator to None.

When to use

Use when you need generator syntax for a sequence of Option steps that should short-circuit on None.

Details

  • Each yield* unwraps a Some value or short-circuits to None
  • The return value is wrapped in Some
  • No Effect runtime is needed

See

  • Do / bind for the do notation alternative

Signature

declare const gen: Gen.Gen<OptionTypeLambda>

Example

(Sequencing Option computations with generator syntax)

import { Option } from "effect"
const maybeName: Option.Option<string> = Option.some("John")
const maybeAge: Option.Option<number> = Option.some(25)
Option.gen(function*() {
const name = (yield* maybeName).toUpperCase()
const age = yield* maybeAge
return { name, age }
}) // => Option.some({ name: "JOHN", age: 25 })

OptionIterator interface

Added in v4.0.0 Source

Iterator protocol used to yield an Option inside gen, returning the contained value type back to the generator.

When to use

Use when defining or typing [Symbol.iterator]() for Option values so yield* can pass the contained value type back into Option.gen.

See

  • gen for writing generator-based Option code that consumes this iterator protocol

Signature

interface OptionIterator<T extends Option<any>> {
next(...args: readonly Array<any>): IteratorResult<T, Value<T>>;
}

Getters

getOrElse

Added in v2.0.0 Source

Extracts the value from a Some, or evaluates a fallback thunk on None.

When to use

Use when providing a default value for an absent Option

  • Unwrapping with lazy evaluation of the fallback

Details

  • Some → returns the inner value
  • None → calls onNone() and returns its result
  • onNone is only called when needed (lazy)

See

Signature

declare const getOrElse: {
<B>(onNone: LazyArg<B>): <A>(self: Option<A>) => B | A;
<A, B>(self: Option<A>, onNone: LazyArg<B>): A | B;
}

Example

(Unwrapping with a fallback)

import { Option } from "effect"
Option.some(1).pipe(Option.getOrElse(() => 0)) // => 1
Option.none().pipe(Option.getOrElse(() => 0)) // => 0

getOrNull

Added in v2.0.0 Source

Extracts the value from a Some, or returns null for None.

When to use

Use when you need to pass absent Option values to APIs that expect null.

Details

  • Some → the inner value
  • Nonenull

See

Signature

declare const getOrNull: <A>(self: Option<A>) => A | null

Example

(Unwrapping to null)

import { Option } from "effect"
Option.getOrNull(Option.some(1)) // => 1
Option.getOrNull(Option.none()) // => null

Extracts the value from a Some, or returns undefined for None.

When to use

Use when you need to pass absent Option values to APIs that expect undefined.

Details

  • Some → the inner value
  • Noneundefined

See

Signature

declare const getOrUndefined: <A>(self: Option<A>) => A | undefined

Example

(Unwrapping to undefined)

import { Option } from "effect"
Option.getOrUndefined(Option.some(1)) // => 1
Option.getOrUndefined(Option.none()) // => undefined

Guards

isNone

Added in v2.0.0 Source

Checks whether an Option is None (absent).

When to use

Use when you need to branch on an absent Option before accessing .value.

Details

  • Acts as a type guard, narrowing to None<A>

See

  • isSome for the opposite check.

Signature

declare const isNone: <A>(self: Option<A>) => self is None<A>

Example

(Checking for None)

import { Option } from "effect"
Option.isNone(Option.some(1)) // => false
Option.isNone(Option.none()) // => true

isOption

Added in v2.0.0 Source

Determines whether the given value is an Option.

When to use

Use to validate unknown values at runtime boundaries, such as type-narrowing in union types.

Details

  • Returns true for both Some and None instances
  • Acts as a type guard, narrowing the input to Option<unknown>

See

  • isNone to check for None specifically
  • isSome to check for Some specifically

Signature

declare const isOption: (input: unknown) => input is Option<unknown>

Example

(Checking if a value is an Option)

import { Option } from "effect"
Option.isOption(Option.some(1)) // => true
Option.isOption(Option.none()) // => true
Option.isOption({}) // => false

isSome

Added in v2.0.0 Source

Checks whether an Option contains a value (Some).

When to use

Use when you need to branch on a present Option before accessing .value.

Details

  • Acts as a type guard, narrowing to Some<A>

See

  • isNone for the opposite check.

Signature

declare const isSome: <A>(self: Option<A>) => self is Some<A>

Example

(Checking for Some)

import { Option } from "effect"
Option.isSome(Option.some(1)) // => true
Option.isSome(Option.none()) // => false

Instances

Creates an Equivalence for Option<A> from an Equivalence for A.

When to use

Use when you need equality to treat two None values as equal and compare two Some values with a supplied equality rule.

Details

  • None vs Nonetrue
  • Some vs None (or vice versa) → false
  • Some(a) vs Some(b) → delegates to the provided Equivalence

Signature

declare function makeEquivalence<A>(isEquivalent: Equivalence<A>): Equivalence<Option<A>>

Example

(Comparing Options)

import { Equivalence, Option } from "effect"
const eq = Option.makeEquivalence(Equivalence.strictEqual<number>())
eq(Option.some(1), Option.some(1)) // => true
eq(Option.some(1), Option.some(2)) // => false
eq(Option.none(), Option.none()) // => true

Lifting

lift2

Added in v2.0.0 Source

Lifts a binary function to operate on two Option values.

When to use

Use when you need to reuse an existing binary function with two Option values.

Details

  • Both Some → applies f and wraps in Some
  • Either NoneNone

See

Signature

declare function lift2<A, B, C>(f: (a: A, b: B) => C): {
(that: Option<B>): (self: Option<A>) => Option<C>;
(self: Option<A>, that: Option<B>): Option<C>;
}

Example

(Lifting addition)

import { Option } from "effect"
const addOptions = Option.lift2((a: number, b: number) => a + b)
addOptions(Option.some(2), Option.some(3)) // => Option.some(5)
addOptions(Option.some(2), Option.none()) // => Option.none()

Lifts a Predicate or Refinement into the Option context: returns Some(value) when the predicate holds, None otherwise.

When to use

Use to convert a boolean check into an Option-returning function

  • Validating input and wrapping it in Option

Details

  • predicate(value) is trueSome(value)
  • predicate(value) is falseNone
  • Supports refinements for type narrowing

See

  • filter to apply a predicate to an existing Option
  • toRefinement for the inverse direction

Signature

declare const liftPredicate: {
<A, B>(refinement: Refinement<A, B>): (a: A) => Option<B>;
<B, A = B>(predicate: Predicate<A>): (b: B) => Option<B>;
<A, B>(self: A, refinement: Refinement<A, B>): Option<B>;
<B, A = B>(self: B, predicate: Predicate<A>): Option<B>;
}

Example

(Validating positive numbers)

import { Option } from "effect"
const parsePositive = Option.liftPredicate((n: number) => n > 0)
parsePositive(1) // => Option.some(1)
parsePositive(-1) // => Option.none()

Mapping

as

Added in v2.0.0 Source

Replaces the value inside a Some with a constant, leaving None unchanged.

When to use

Use when you need to replace a present Option value while preserving whether it was Some or None.

See

  • asVoid to replace with undefined
  • map for a general transformation

Signature

declare const as: {
<B>(b: B): <X>(self: Option<X>) => Option<B>;
<X, B>(self: Option<X>, b: B): Option<B>;
}

Example

(Replacing a value)

import { Option } from "effect"
Option.as(Option.some(42), "new value") // => Option.some("new value")
Option.as(Option.none(), "new value") // => Option.none()

asVoid

Added in v2.0.0 Source

Replaces the value inside a Some with void (undefined), leaving None unchanged.

When to use

Use when you need to discard a present Option value while preserving whether it was Some or None.

See

  • as to replace with a specific constant

Signature

declare const asVoid: <_>(self: Option<_>) => Option<void>

Example

(Voiding the value)

import { Option } from "effect"
Option.asVoid(Option.some(42)) // => Option.some(undefined)
Option.asVoid(Option.none()) // => Option.none()

bindTo

Added in v2.0.0 Source

Gives a name to the value of an Option, creating a single-key record inside Some. Starting point for the do notation pipeline.

When to use

Use when you need to start an Option do notation chain by naming the first value.

See

  • Do for starting with an empty record
  • bind to add Option values
  • let to add plain values

Signature

declare const bindTo: {
<N extends string>(name: N): <A>(self: Option<A>) => Option<{ [K in string]: A }>;
<A, N extends string>(self: Option<A>, name: N): Option<{ [K in string]: A }>;
}

Example

(Starting do notation)

import { Option, pipe } from "effect"
pipe(
Option.some(2),
Option.bindTo("x"),
Option.bind("y", () => Option.some(3)),
Option.let("sum", ({ x, y }) => x + y)
) // => Option.some({ x: 2, y: 3, sum: 5 })

map

Added in v2.0.0 Source

Transforms the value inside a Some using the provided function, leaving None unchanged.

When to use

Use to apply a pure transformation to an Option's present value, especially when chaining transformations in a pipeline.

Details

  • Some → applies f and wraps the result in a new Some
  • None → returns None unchanged

See

  • flatMap when f returns an Option
  • as to replace the value with a constant

Signature

declare const map: {
<A, B>(f: (a: A) => B): (self: Option<A>) => Option<B>;
<A, B>(self: Option<A>, f: (a: A) => B): Option<B>;
}

Example

(Mapping over an Option)

import { Option } from "effect"
Option.map(Option.some(2), (n) => n * 2) // => Option.some(4)
Option.map(Option.none(), (n: number) => n * 2) // => Option.none()

Models

None interface

Added in v2.0.0 Source

Represents the absence of a value within an Option.

When to use

Use as a type guard target when narrowing via isNone

Details

  • _tag is always "None"
  • Implements Pipeable, Inspectable, and structural equality

See

  • isNone to check if an Option is None
  • none to construct a None

Signature

interface None<out A> extends Pipeable, Inspectable {
readonly _op: "None";
readonly _tag: "None";
[ignoreSymbol]?: OptionUnifyIgnore;
[typeSymbol]?: unknown;
[unifySymbol]?: OptionUnify<None<A>>;
readonly "~effect/data/Option": {
readonly _A: Covariant<A>;
};
readonly valueOrUndefined: undefined;
[iterator](): OptionIterator<Option<A>>;
}

Option type

Added in v2.0.0 Source

The Option data type represents optional values. An Option<A> is either Some<A>, containing a value of type A, or None, representing absence.

When to use

Use to represent initial values that may not yet exist

  • Returning from partial functions (not defined for all inputs)
  • Managing optional fields in data structures

See

  • some for creating a Some
  • none for creating a None
  • match for pattern matching

Signature

type Option<A> = None<A> | Some<A>

OptionUnify interface

Added in v2.0.0 Source

Type-level unification support for Option values.

When to use

Use when extending Effect's type-level unification support for Option.

Details

This is used by Effect's Unify machinery to preserve the contained value type when generic code returns or combines Option values. Users normally do not need to reference this interface directly.

Signature

interface OptionUnify<A extends {
[typeSymbol]?: any;
}> {
Option?: () => A[typeof typeSymbol] extends Option<A0> | _ ? Option<A0> : never;
}

OptionUnifyIgnore interface

Added in v2.0.0 Source

Marker interface used by Effect's Unify machinery for Option values.

When to use

Use when marking generic code so Option unification should be ignored.

Details

This supports type-level unification behavior for Option. Users normally do not need to reference this interface directly.

Signature

interface OptionUnifyIgnore {}

Some interface

Added in v2.0.0 Source

Represents the presence of a value within an Option.

When to use

Use as a type guard target when narrowing via isSome

  • Access the inner value via .value

Details

  • _tag is always "Some"
  • .value holds the contained value of type A
  • Implements Pipeable, Inspectable, and structural equality

See

  • isSome to check if an Option is Some
  • some to construct a Some

Signature

interface Some<out A> extends Pipeable, Inspectable {
readonly _op: "Some";
readonly _tag: "Some";
[ignoreSymbol]?: OptionUnifyIgnore;
[typeSymbol]?: unknown;
[unifySymbol]?: OptionUnify<Some<A>>;
readonly "~effect/data/Option": {
readonly _A: Covariant<A>;
};
readonly value: A;
readonly valueOrUndefined: A;
[iterator](): OptionIterator<Option<A>>;
}

Other

Signature

declare const let: {
<N extends string, A extends object, B>(name: Exclude<N, keyof A>, f: (a: NoInfer<A>) => B): (self: Option<A>) => Option<{ [K in string | number | symbol]: K extends keyof A ? A[K] : B }>;
<A extends object, N extends string, B>(self: Option<A>, name: Exclude<N, keyof A>, f: (a: NoInfer<A>) => B): Option<{ [K in string | number | symbol]: K extends keyof A ? A[K] : B }>;
}

Option

Added in v2.0.0 Source

Namespace containing utility types for Option.

When to use

Use to access type-level helpers associated with Option.

Signature

declare const void: Option<void>

Pattern Matching

match

Added in v2.0.0 Source

Pattern-matches on an Option, handling both None and Some cases.

When to use

Use when you need to handle both Some and None in one expression and transform an Option into a plain value.

Details

  • If None, calls onNone and returns its result
  • If Some, calls onSome with the value and returns its result
  • Supports the dual API (data-last and data-first)

See

Signature

declare const match: {
<B, A, C = B>(options: {
readonly onNone: LazyArg<B>;
readonly onSome: (a: A) => C;
}): (self: Option<A>) => B | C;
<A, B, C = B>(self: Option<A>, options: {
readonly onNone: LazyArg<B>;
readonly onSome: (a: A) => C;
}): B | C;
}

Example

(Matching on an Option)

import { Option } from "effect"
Option.match(Option.some(1), {
onNone: () => "Option is empty",
onSome: (value) => `Option has a value: ${value}`
}) // => "Option has a value: 1"

Predicates

contains

Added in v2.0.0 Source

Checks whether an Option contains a value equal to the given one, using default structural equality.

When to use

Use when you need a quick membership test for an Option value using standard equality.

Details

  • Some where Equal.equals(value, a) is truetrue
  • Some where not equal, or Nonefalse

See

Signature

declare const contains: {
<A>(a: A): (self: Option<A>) => boolean;
<A>(self: Option<A>, a: A): boolean;
}

Example

(Checking containment)

import { Option } from "effect"
Option.some(2).pipe(Option.contains(2)) // => true
Option.some(1).pipe(Option.contains(2)) // => false
Option.none().pipe(Option.contains(2)) // => false

containsWith

Added in v2.0.0 Source

Checks whether an Option contains a value equivalent to the given one, using a custom Equivalence.

When to use

Use when you need to test whether an Option contains a value using a custom equality check.

Details

  • Some where isEquivalent(value, a) is truetrue
  • Some where not equivalent, or Nonefalse

See

  • contains for a version using default equality

Signature

declare function containsWith<A>(isEquivalent: (self: A, that: A) => boolean): {
(a: A): (self: Option<A>) => boolean;
(self: Option<A>, a: A): boolean;
}

Example

(Checking with custom equivalence)

import { Equivalence, Option } from "effect"
const check = Option.containsWith(Equivalence.strictEqual<number>())
Option.some(2).pipe(check(2)) // => true
Option.some(1).pipe(check(2)) // => false
Option.none().pipe(check(2)) // => false

exists

Added in v2.0.0 Source

Checks whether the value in a Some satisfies a predicate or refinement.

When to use

Use to check a condition on an optional value without unwrapping

Details

  • Nonefalse
  • Some where predicate(value) is truetrue
  • Some where predicate(value) is falsefalse
  • With a refinement, narrows the Option type on true

See

  • filter to keep or discard based on a predicate
  • contains to test for a specific value

Signature

declare const exists: {
<A, B>(refinement: Refinement<NoInfer<A>, B>): (self: Option<A>) => self is Option<B>;
<A>(predicate: Predicate<NoInfer<A>>): (self: Option<A>) => boolean;
<A, B>(self: Option<A>, refinement: Refinement<A, B>): self is Option<B>;
<A>(self: Option<A>, predicate: Predicate<A>): boolean;
}

Example

(Testing a condition)

import { Option } from "effect"
const isEven = (n: number) => n % 2 === 0
Option.some(2).pipe(Option.exists(isEven)) // => true
Option.some(1).pipe(Option.exists(isEven)) // => false
Option.none().pipe(Option.exists(isEven)) // => false

Sequencing

andThen

Added in v2.0.0 Source

Chains a second computation onto an Option. The second value can be a plain value, an Option, or a function returning either.

When to use

Use when you need to chain an Option with a next step that may be another Option, a plain value, or a function.

Details

  • If self is None, returns None immediately
  • If f is a function, calls it with the Some value
  • If f returns an Option, returns it as-is; if a plain value, wraps in Some
  • If f is not a function, uses it directly (same wrapping rules)

See

  • flatMap for the standard monadic bind
  • map when you always return a plain value

Signature

declare const andThen: {
<A, B>(f: (a: A) => Option<B>): (self: Option<A>) => Option<B>;
<B>(f: Option<B>): <A>(self: Option<A>) => Option<B>;
<A, B>(f: (a: A) => B): (self: Option<A>) => Option<B>;
<B>(f: NotFunction<B>): <A>(self: Option<A>) => Option<B>;
<A, B>(self: Option<A>, f: (a: A) => Option<B>): Option<B>;
<A, B>(self: Option<A>, f: Option<B>): Option<B>;
<A, B>(self: Option<A>, f: (a: A) => B): Option<B>;
<A, B>(self: Option<A>, f: NotFunction<B>): Option<B>;
}

Example

(Chaining with andThen)

import { Option } from "effect"
// Chain with a function returning Option
Option.andThen(Option.some(5), (x) => Option.some(x * 2)) // => Option.some(10)
// Chain with a static value
Option.andThen(Option.some(5), "hello") // => Option.some("hello")
// Chain with None - skips
Option.andThen(Option.none(), (x) => Option.some(x * 2)) // => Option.none()

bind

Added in v2.0.0 Source

Adds an Option value to the do notation record under a given name. If the Option is None, the whole pipeline short-circuits to None.

When to use

Use when you need to sequence Option computations in do notation.

See

  • Do for starting the chain
  • let to add plain values
  • bindTo to start by naming an existing Option

Signature

declare const bind: {
<N extends string, A extends object, B>(name: Exclude<N, keyof A>, f: (a: NoInfer<A>) => Option<B>): (self: Option<A>) => Option<{ [K in string | number | symbol]: K extends keyof A ? A[K] : B }>;
<A extends object, N extends string, B>(self: Option<A>, name: Exclude<N, keyof A>, f: (a: NoInfer<A>) => Option<B>): Option<{ [K in string | number | symbol]: K extends keyof A ? A[K] : B }>;
}

Example

(Binding Option values)

import { Option, pipe } from "effect"
pipe(
Option.Do,
Option.bind("x", () => Option.some(2)),
Option.bind("y", () => Option.some(3)),
Option.let("sum", ({ x, y }) => x + y),
Option.filter(({ x, y }) => x * y > 5)
) // => Option.some({ x: 2, y: 3, sum: 5 })

composeK

Added in v2.0.0 Source

Composes two Option-returning functions into a single function that chains them together.

When to use

Use when you need to compose two functions that each return an Option, so None short-circuits without calling the next function.

Details

  • Calls afb(a), then if Some, calls bfc with its value
  • Short-circuits to None if either function returns None

See

Signature

declare const composeK: {
<B, C>(bfc: (b: B) => Option<C>): <A>(afb: (a: A) => Option<B>) => (a: A) => Option<C>;
<A, B, C>(afb: (a: A) => Option<B>, bfc: (b: B) => Option<C>): (a: A) => Option<C>;
}

Example

(Composing parsers)

import { Option } from "effect"
const parse = (s: string): Option.Option<number> =>
isNaN(Number(s)) ? Option.none() : Option.some(Number(s))
const double = (n: number): Option.Option<number> =>
n > 0 ? Option.some(n * 2) : Option.none()
const parseAndDouble = Option.composeK(parse, double)
parseAndDouble("42") // => Option.some(84)
parseAndDouble("not a number") // => Option.none()

flatMap

Added in v2.0.0 Source

Applies a function that returns an Option to the value of a Some, flattening the result. Returns None if the input is None.

When to use

Use when you need to chain dependent Option computations where each step may return None.

Details

  • Some → applies f to the value and returns its Option result
  • None → returns None without calling f
  • Equivalent to map followed by flatten

See

  • map when f returns a plain value
  • andThen for a more flexible variant
  • flatten to unwrap a nested Option<Option<A>>

Signature

declare const flatMap: {
<A, B>(f: (a: A) => Option<B>): (self: Option<A>) => Option<B>;
<A, B>(self: Option<A>, f: (a: A) => Option<B>): Option<B>;
}

Example

(Chaining optional lookups)

import { Option } from "effect"
interface User {
readonly name: string
readonly address: Option.Option<{ readonly street: Option.Option<string> }>
}
const user: User = {
name: "John",
address: Option.some({ street: Option.some("123 Main St") })
}
user.address.pipe(
Option.flatMap((addr) => addr.street)
) // => Option.some("123 Main St")

Combines flatMap with fromNullishOr: applies a function that may return null/undefined to the value of a Some.

When to use

Use when you need to chain optional computations that use null or undefined instead of Option, such as nested property access.

Details

See

Signature

declare const flatMapNullishOr: {
<A, B>(f: (a: A) => B): (self: Option<A>) => Option<NonNullable<B>>;
<A, B>(self: Option<A>, f: (a: A) => B): Option<NonNullable<B>>;
}

Example

(Navigating optional properties)

import { Option } from "effect"
interface Employee {
company?: { address?: { street?: { name?: string } } }
}
const emp: Employee = {
company: { address: { street: { name: "high street" } } }
}
Option.some(emp).pipe(
Option.flatMapNullishOr((e) => e.company?.address?.street?.name)
) // => Option.some("high street")

flatten

Added in v2.0.0 Source

Flattens a nested Option<Option<A>> into Option<A>.

When to use

Use when you need to remove one layer of nested Option.

Details

  • Some(Some(value))Some(value)
  • Some(None)None
  • NoneNone

See

Signature

declare const flatten: <A>(self: Option<Option<A>>) => Option<A>

Example

(Flattening nested Options)

import { Option } from "effect"
Option.flatten(Option.some(Option.some("value"))) // => Option.some("value")
Option.flatten(Option.some(Option.none())) // => Option.none()

tap

Added in v2.0.0 Source

Runs a side-effecting Option-returning function on the value of a Some, returning the original Option if the function returns Some, or None if it returns None.

When to use

Use to validate an Option's present value without transforming it, such as adding a side-condition check in a pipeline.

Details

  • NoneNone
  • Some → calls f(value); if result is Some, returns original self; if None, returns None

See

  • flatMap when you want to transform the value
  • filter for predicate-based filtering

Signature

declare const tap: {
<A, X>(f: (a: A) => Option<X>): (self: Option<A>) => Option<A>;
<A, X>(self: Option<A>, f: (a: A) => Option<X>): Option<A>;
}

Example

(Validating without transforming)

import { Option } from "effect"
const getInteger = (n: number) =>
Number.isInteger(n) ? Option.some(n) : Option.none()
Option.tap(Option.some(1), getInteger) // => Option.some(1)
Option.tap(Option.some(1.14), getInteger) // => Option.none()

Sorting

makeOrder

Added in v4.0.0 Source

Creates an Order for Option<A> from an Order for A.

When to use

Use when you need to sort Some and None values, with None ordered before present values and present values compared by a supplied ordering rule.

Details

  • None is considered less than any Some
  • Two Some values are compared using the provided Order
  • Two None values are equal (returns 0)

Signature

declare function makeOrder<A>(O: Order<A>): Order<Option<A>>

Example

(Ordering Options)

import { Number as N, Option } from "effect"
const ord = Option.makeOrder(N.Order)
ord(Option.none(), Option.some(1)) // => -1
ord(Option.some(1), Option.none()) // => 1
ord(Option.some(1), Option.some(2)) // => -1

Utility Types

OptionTypeLambda interface

Added in v2.0.0 Source

Type lambda interface for higher-kinded type encodings with Option.

When to use

Use when defining higher-kinded abstractions that must accept optional-value types as one of their type-lambda inputs.

Signature

interface OptionTypeLambda extends TypeLambda {
readonly type: Option<unknown>;
}

Zipping

zipLeft

Added in v2.0.0 Source

Sequences two Options, keeping the value from the first if both are Some.

When to use

Use when you need two Option values to both be Some, then keep only the first value.

Details

  • Both Some → returns self
  • Either None → returns None

See

Signature

declare const zipLeft: {
<_>(that: Option<_>): <A>(self: Option<A>) => Option<A>;
<A, X>(self: Option<A>, that: Option<X>): Option<A>;
}

Example

(Keeping the first value)

import { Option } from "effect"
Option.zipLeft(Option.some("hello"), Option.some(1)) // => Option.some("hello")
Option.zipLeft(Option.some("hello"), Option.none()) // => Option.none()

zipRight

Added in v2.0.0 Source

Sequences two Options, keeping the value from the second if both are Some.

When to use

Use when you need two Option values to both be Some, then keep only the second value.

Details

  • Both Some → returns that
  • Either None → returns None

See

  • zipLeft to keep the first value instead
  • zipWith to combine both values

Signature

declare const zipRight: {
<B>(that: Option<B>): <_>(self: Option<_>) => Option<B>;
<X, B>(self: Option<X>, that: Option<B>): Option<B>;
}

Example

(Keeping the second value)

import { Option } from "effect"
Option.zipRight(Option.some(1), Option.some("hello")) // => Option.some("hello")
Option.zipRight(Option.none(), Option.some("hello")) // => Option.none()

zipWith

Added in v2.0.0 Source

Combines two Options using a provided function.

When to use

Use when you need to combine two present Option values into a computed result.

Details

  • Both Some → applies f(a, b) and wraps in Some
  • Either NoneNone

See

  • product to combine into a tuple instead
  • lift2 to lift a binary function

Signature

declare const zipWith: {
<B, A, C>(that: Option<B>, f: (a: A, b: B) => C): (self: Option<A>) => Option<C>;
<A, B, C>(self: Option<A>, that: Option<B>, f: (a: A, b: B) => C): Option<C>;
}

Example

(Combining with a function)

import { Option } from "effect"
Option.zipWith(
Option.some("John"),
Option.some(25),
(name, age) => ({ name: name.toUpperCase(), age })
) // => Option.some({ name: "JOHN", age: 25 })