Skip to content
Effect 4.0 is here. One ecosystem. Zero dependencies.

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 Since v2.0.0 Source

Combining

Since v2.0.0

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 })
Since v2.0.0

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 Some โ†’ Some([a, b])
  • Either None โ†’ None

See

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

Signature

declare const product: {
<B>(that: Option<B>): <A>(self: Option<A>) => Option<[A, B]>;
<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()

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 Some โ†’ Some([self.value, ...rest])
  • Any None โ†’ None

See

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

Signature

declare const productMany: {
<A>(collection: Iterable<Option<A>>): (self: Option<A>) => Option<[A, ...Array<A>]>;
<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

Since v2.0.0

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 })

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 + None โ†’ None
  • 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()

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 + None โ†’ None
  • Some(a) + None โ†’ Some(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()
Since v2.0.0

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()
Since v2.0.0

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 undefined โ†’ None
  • 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)

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

  • null โ†’ None
  • 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

  • undefined โ†’ None
  • 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)

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")

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"

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()
Since v2.0.0

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()) // => []

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

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)
Since v2.0.0

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")

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 Some โ†’ Some(Result.fail(value)) (value from primary)
  • self is None, that() is Some โ†’ Some(Result.succeed(value)) (value from fallback)
  • Both None โ†’ None

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"))

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

Since v2.0.0

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

  • None โ†’ None
  • Some where predicate(value) is true โ†’ Some(value)
  • Some where predicate(value) is false โ†’ None
  • 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()

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")

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 success and failure channels using a Result-returning function.

Details

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

See

  • filter for simple predicate-based filtering

Signature

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

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.some(42), Option.none()]
Option.partitionMap(Option.some("abc"), parseNumber) // => [Option.none(), Option.some("Not a number")]
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

Since v2.0.0

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 })
Since v4.0.0

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

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

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
  • None โ†’ null

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
  • None โ†’ undefined

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

Since v2.0.0

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
Since v2.0.0

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
Since v2.0.0

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 None โ†’ true
  • 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

Since v2.0.0

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 None โ†’ None

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 true โ†’ Some(value)
  • predicate(value) is false โ†’ None
  • 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

Since v2.0.0

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()
Since v2.0.0

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()
Since v2.0.0

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 })
Since v2.0.0

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
Since v2.0.0

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/Option": {
readonly _A: Covariant<A>;
};
readonly valueOrUndefined: undefined;
[iterator](): OptionIterator<Option<A>>;
}
Since v2.0.0

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
Since v2.0.0

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;
}
Since v2.0.0

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
Since v2.0.0

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/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 }>;
}
Since v2.0.0

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

Since v2.0.0

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

Since v2.0.0

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 true โ†’ true
  • Some where not equal, or None โ†’ false

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

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 true โ†’ true
  • Some where not equivalent, or None โ†’ false

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
Since v2.0.0

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

  • None โ†’ false
  • Some where predicate(value) is true โ†’ true
  • Some where predicate(value) is false โ†’ false
  • 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

Since v2.0.0

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()
Since v2.0.0

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 })
Since v2.0.0

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()
Since v2.0.0

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

  • None โ†’ None
  • Some โ†’ applies f, then wraps via fromNullishOr

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")
Since v2.0.0

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
  • None โ†’ None

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()
Since v2.0.0

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

  • None โ†’ None
  • 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

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

Since v2.0.0

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

Since v2.0.0

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()
Since v2.0.0

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()
Since v2.0.0

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 None โ†’ None

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 })