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.
Combining
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 →
Optionof a tuple with the same length - Struct input →
Optionof a struct with the same keys - Iterable input →
Optionof anArray - Any
Nonein the input → entire result isNone
See
- product for combining exactly two
- productMany for a homogeneous collection
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 })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
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
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
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
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
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
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
Nonefor 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()makeCombinerFailFast
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
- makeReducerFailFast to get a full
Reducer
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
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→NoneSome(a)+None→Some(a)None+Some(b)→Some(b)Some(a)+Some(b)→Some(combine(a, b))- Initial value is
None
See
- makeReducerFailFast for fail-fast semantics
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)makeReducerFailFast
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
Nonecauses the result to becomeNoneimmediately
See
- makeCombinerFailFast for just the combiner
- makeReducer for non-fail-fast semantics
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()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 ofOption<A>for anyA - 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()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
nullorundefined; 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
fromNullishOr
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
nullorundefined→None- Any other value →
Some(typed asNonNullable<A>)
See
- fromNullOr to only treat
nullas absent - fromUndefinedOr to only treat
undefinedas absent - liftNullishOr to lift a nullable-returning function
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
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
- fromNullishOr to treat both
nullandundefinedas absent - fromUndefinedOr to only treat
undefinedas absent
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)fromUndefinedOr
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
- fromNullishOr to treat both
nullandundefinedas absent - fromNullOr to only treat
nullas absent
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
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
FailurebecomesSomewith the failure valueSuccessbecomesNoneand the success value is discarded
See
- getSuccess for the opposite operation.
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
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 valueNone→ throwsnew Error("getOrThrow called on a None")
See
- getOrThrowWith for a custom error
- getOrElse for a non-throwing alternative
Signature
declare const getOrThrow: <A>(self: Option<A>) => AExample
(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"getOrThrowWith
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 valueNone→ throws the value returned byonNone()
See
- getOrThrow for a version with a default error
- getOrElse for a non-throwing alternative
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
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
SuccessbecomesSomewith the success valueFailurebecomesNoneand the failure value is discarded
See
- getFailure for the opposite operation.
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()liftNullishOr
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
- fromNullishOr for converting a single value
- liftThrowable for functions that throw instead
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()liftThrowable
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 →
Somewith the result - If the function throws →
None(exception is swallowed)
See
- liftNullishOr for nullable-returning functions
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()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
- fromIterable for the inverse direction
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
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
truewhen the original function returnsSome - Returns
falsewhen the original function returnsNone - Narrows the input type to
Bon success
See
- liftPredicate for the reverse direction
Signature
declare function toRefinement<A, B>(f: (a: A) => Option<B>): (a: A) => a is BExample
(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") // => trueisString(1) // => falseError Handling
firstSomeOf
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
Noneonly when every element isNone
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> : neverExample
(Finding the first Some)
import { Option } from "effect"
Option.firstSomeOf([ Option.none(), Option.some(1), Option.some(2)]) // => Option.some(1)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→ returnsselfunchangedNone→ evaluates and returnsthat()thatis lazily evaluated
See
- orElseSome to wrap the fallback value in
Someautomatically - firstSomeOf to pick the first
Somefrom 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
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
selfisSome→Some(Result.fail(value))(value from primary)selfisNone,that()isSome→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"))orElseSome
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→ returnsselfunchangedNone→ callsonNone(), wraps result inSome, 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
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→NoneSomewherepredicate(value)istrue→Some(value)Somewherepredicate(value)isfalse→None- Supports refinements for type narrowing
See
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")partitionMap
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]SomewherefreturnsErr→[Some(error), None]SomewherefreturnsOk→[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
reduceCompact
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
fonly toSomevalues Nonevalues 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)) // => 3Generators
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 aSomevalue or short-circuits toNone - The return value is wrapped in
Some - No
Effectruntime is needed
See
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
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
Optioncode 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 valueNone→ callsonNone()and returns its resultonNoneis only called when needed (lazy)
See
- getOrNull to fall back to
null - getOrUndefined to fall back to
undefined - getOrThrow to throw on
None
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)) // => 1Option.none().pipe(Option.getOrElse(() => 0)) // => 0Extracts 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 valueNone→null
See
- getOrUndefined to return
undefinedinstead - getOrElse for a custom fallback
Signature
declare const getOrNull: <A>(self: Option<A>) => A | nullExample
(Unwrapping to null)
import { Option } from "effect"
Option.getOrNull(Option.some(1)) // => 1Option.getOrNull(Option.none()) // => nullgetOrUndefined
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 valueNone→undefined
See
Signature
declare const getOrUndefined: <A>(self: Option<A>) => A | undefinedExample
(Unwrapping to undefined)
import { Option } from "effect"
Option.getOrUndefined(Option.some(1)) // => 1Option.getOrUndefined(Option.none()) // => undefinedGuards
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)) // => falseOption.isNone(Option.none()) // => trueDetermines 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
truefor bothSomeandNoneinstances - Acts as a type guard, narrowing the input to
Option<unknown>
See
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)) // => trueOption.isOption(Option.none()) // => trueOption.isOption({}) // => falseChecks 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)) // => trueOption.isSome(Option.none()) // => falseInstances
makeEquivalence
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
NonevsNone→trueSomevsNone(or vice versa) →falseSome(a)vsSome(b)→ delegates to the providedEquivalence
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)) // => trueeq(Option.some(1), Option.some(2)) // => falseeq(Option.none(), Option.none()) // => trueLifting
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→ appliesfand wraps inSome - Either
None→None
See
- zipWith for a non-lifted variant
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()liftPredicate
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)istrue→Some(value)predicate(value)isfalse→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
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
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()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()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
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 })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→ appliesfand wraps the result in a newSomeNone→ returnsNoneunchanged
See
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
Represents the absence of a value within an Option.
When to use
Use as a type guard target when narrowing via isNone
Details
_tagis always"None"- Implements
Pipeable,Inspectable, and structural equality
See
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>>;}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
Signature
type Option<A> = None<A> | Some<A>OptionUnify interface
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
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 {}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
_tagis always"Some".valueholds the contained value of typeA- Implements
Pipeable,Inspectable, and structural equality
See
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 }>;}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
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, callsonNoneand returns its result - If
Some, callsonSomewith the value and returns its result - Supports the
dualAPI (data-last and data-first)
See
- getOrElse for unwrapping with a default
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
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
SomewhereEqual.equals(value, a)istrue→trueSomewhere not equal, orNone→false
See
- containsWith for custom equality
- exists to test with a predicate
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)) // => trueOption.some(1).pipe(Option.contains(2)) // => falseOption.none().pipe(Option.contains(2)) // => falsecontainsWith
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
SomewhereisEquivalent(value, a)istrue→trueSomewhere not equivalent, orNone→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)) // => trueOption.some(1).pipe(check(2)) // => falseOption.none().pipe(check(2)) // => falseChecks 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→falseSomewherepredicate(value)istrue→trueSomewherepredicate(value)isfalse→false- With a refinement, narrows the
Optiontype ontrue
See
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)) // => trueOption.some(1).pipe(Option.exists(isEven)) // => falseOption.none().pipe(Option.exists(isEven)) // => falseSequencing
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
selfisNone, returnsNoneimmediately - If
fis a function, calls it with theSomevalue - If
freturns anOption, returns it as-is; if a plain value, wraps inSome - If
fis not a function, uses it directly (same wrapping rules)
See
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 OptionOption.andThen(Option.some(5), (x) => Option.some(x * 2)) // => Option.some(10)
// Chain with a static valueOption.andThen(Option.some(5), "hello") // => Option.some("hello")
// Chain with None - skipsOption.andThen(Option.none(), (x) => Option.some(x * 2)) // => Option.none()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
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 })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 ifSome, callsbfcwith its value - Short-circuits to
Noneif either function returnsNone
See
- flatMap for single-step chaining
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()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→ appliesfto the value and returns itsOptionresultNone→ returnsNonewithout callingf- Equivalent to
mapfollowed by flatten
See
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")flatMapNullishOr
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→NoneSome→ appliesf, then wraps via fromNullishOr
See
- flatMap when the function already returns
Option - fromNullishOr for single-value conversion
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")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)→NoneNone→None
See
- flatMap which is
map+flatten
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()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→NoneSome→ callsf(value); if result isSome, returns originalself; ifNone, returnsNone
See
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
Noneis considered less than anySome- Two
Somevalues are compared using the providedOrder - Two
Nonevalues are equal (returns0)
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)) // => -1ord(Option.some(1), Option.none()) // => 1ord(Option.some(1), Option.some(2)) // => -1Utility Types
OptionTypeLambda interface
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
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→ returnsself - Either
None→ returnsNone
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()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→ returnsthat - Either
None→ returnsNone
See
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()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→ appliesf(a, b)and wraps inSome - Either
None→None
See
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 })