Option
Combining
Combines a structure of Options into a single Option containing the
values with the same structure.
Details
This function takes a structure of Options (a tuple, struct, or iterable)
and produces a single Option that contains the values from the input
structure if all Options are Some. If any Option in the input is
None, the result is None. The structure of the input is preserved in the
output.
- If the input is a tuple (e.g., an array), the result will be an
Optioncontaining a tuple with the same length. - If the input is a struct (e.g., an object), the result will be an
Optioncontaining a struct with the same keys. - If the input is an iterable, the result will be an
Optioncontaining an array.
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
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])console.log(tuple)// Output:// { _id: 'Option', _tag: 'Some', value: [ 'John', 25 ] }
// ┌─── Option<{ name: string; age: number; }>// ▼const struct = Option.all({ name: maybeName, age: maybeAge })console.log(struct)// Output:// { _id: 'Option', _tag: 'Some', value: { name: 'John', age: 25 } }Applies a function inside a Some to a value inside another Some,
combining them into a new Option.
Details
This function allows you to apply a function wrapped in an Option (self)
to a value wrapped in another Option (that). If both Options are
Some, the function is applied to the value, and the result is wrapped in a
new Some. If either Option is None, the result is None.
Signature
declare const ap: { <A>(that: Option<A>): <B>(self: Option<(a: A) => B>) => Option<B>; <A, B>(self: Option<(a: A) => B>, that: Option<A>): Option<B>;}Combines two Option values into a single Option containing a tuple of
their values if both are Some.
Details
This function takes two Options and combines their values into a tuple [A, B] if both are Some. If either of the Options is None, the result is
None. This is particularly useful for combining multiple Option values
into a single one, ensuring both contain valid values.
Signature
declare function product<A, B>(self: Option<A>, that: Option<B>): Option<[A, B]>productMany
Combines an Option with a collection of Options into a single Option
containing a tuple of their values if all are Some.
Details
This function takes a primary Option and a collection of Options and
combines their values into a tuple [A, ...Array<A>] if all are Some. If
the primary Option or any Option in the collection is None, the result
is None.
Signature
declare function productMany<A>(self: Option<A>, collection: Iterable<Option<A>>): Option<[A, ...Array<A>]>Constructors
fromIterable
Converts an Iterable into an Option, wrapping the first element if it
exists.
Details
This function takes an Iterable (e.g., an array, a generator, or any object
implementing the Iterable interface) and returns an Option based on its
content:
- If the
Iterablecontains at least one element, the first element is wrapped in aSomeand returned. - If the
Iterableis empty,Noneis returned, representing the absence of a value.
This utility is useful for safely handling collections that might be empty, ensuring you explicitly handle both cases where a value exists or doesn't.
Signature
declare function fromIterable<A>(collection: Iterable<A>): Option<A>Example
import { Option } from "effect"
console.log(Option.fromIterable([1, 2, 3]))// Output: { _id: 'Option', _tag: 'Some', value: 1 }
console.log(Option.fromIterable([]))// Output: { _id: 'Option', _tag: 'None' }Represents the absence of a value by creating an empty Option.
Option.none returns an Option<never>, which is a subtype of Option<A>.
This means you can use it in place of any Option<A> regardless of the type
A.
See
- some for the opposite operation.
Signature
declare function none<A = never>(): Option<A>Example
(Creating an Option with No Value)
import { Option } from "effect"
// An Option holding no value//// ┌─── Option<never>// ▼const noValue = Option.none()
console.log(noValue)// Output: { _id: 'Option', _tag: 'None' }Signature
declare const some: <A>(value: A) => Option<A>Example
(Creating an Option with a Value)
import { Option } from "effect"
// An Option holding the number 1//// ┌─── Option<number>// ▼const value = Option.some(1)
console.log(value)// Output: { _id: 'Option', _tag: 'Some', value: 1 }Conversions
fromNullable
Converts a nullable value into an Option. Returns None if the value is
null or undefined, otherwise wraps the value in a Some.
Signature
declare function fromNullable<A>(nullableValue: A): Option<NonNullable<A>>Example
import { Option } from "effect"
console.log(Option.fromNullable(undefined))// Output: { _id: 'Option', _tag: 'None' }
console.log(Option.fromNullable(null))// Output: { _id: 'Option', _tag: 'None' }
console.log(Option.fromNullable(1))// Output: { _id: 'Option', _tag: 'Some', value: 1 }Converts an Either into an Option by discarding the right value and
extracting the left value.
Details
This function transforms an Either into an Option as follows:
- If the
Eitheris aLeft, its value is wrapped in aSomeand returned. - If the
Eitheris aRight, the value is discarded, andNoneis returned.
This utility is useful when you only care about the error case (Left) of an
Either and want to handle it as an Option. By discarding the right value,
it simplifies error-focused workflows.
See
- getRight for the opposite operation.
Signature
declare const getLeft: <R, L>(self: Either<R, L>) => Option<L>Example
import { Either, Option } from "effect"
console.log(Option.getLeft(Either.right("ok")))// Output: { _id: 'Option', _tag: 'None' }
console.log(Option.getLeft(Either.left("err")))// Output: { _id: 'Option', _tag: 'Some', value: 'err' }getOrThrow
Extracts the value of an Option or throws a default error if the Option
is None.
Details
This function extracts the value from an Option if it is Some. If the
Option is None, it throws a default error. It is useful for fail-fast
scenarios where the absence of a value is treated as an exceptional case and
a default error is sufficient.
See
- getOrThrowWith for a version that allows you to provide a custom error.
Signature
declare const getOrThrow: <A>(self: Option<A>) => AExample
import * as assert from "node:assert"import { Option } from "effect"
assert.deepStrictEqual(Option.getOrThrow(Option.some(1)), 1)assert.throws(() => Option.getOrThrow(Option.none()))getOrThrowWith
Extracts the value of an Option or throws an error if the Option is
None, using a custom error factory.
Details
This function allows you to extract the value of an Option when it is
Some. If the Option is None, it throws an error generated by the
provided onNone function. This utility is particularly useful when you need
a fail-fast behavior for empty Option values and want to provide a custom
error message or object.
See
- getOrThrow for a version that throws a default error.
Signature
declare const getOrThrowWith: { (onNone: () => unknown): <A>(self: Option<A>) => A; <A>(self: Option<A>, onNone: () => unknown): A;}Example
import * as assert from "node:assert"import { Option } from "effect"
assert.deepStrictEqual( Option.getOrThrowWith(Option.some(1), () => new Error('Unexpected None')), 1)assert.throws(() => Option.getOrThrowWith(Option.none(), () => new Error('Unexpected None')))Converts an Either into an Option by discarding the error and extracting
the right value.
Details
This function takes an Either and returns an Option based on its value:
- If the
Eitheris aRight, its value is wrapped in aSomeand returned. - If the
Eitheris aLeft, the error is discarded, andNoneis returned.
This is particularly useful when you only care about the success case
(Right) of an Either and want to handle the result using Option. By
using this function, you can convert Either into a simpler structure for
cases where error handling is not required.
See
- getLeft for the opposite operation.
Signature
declare const getRight: <R, L>(self: Either<R, L>) => Option<R>Example
import { Either, Option } from "effect"
console.log(Option.getRight(Either.right("ok")))// Output: { _id: 'Option', _tag: 'Some', value: 'ok' }
console.log(Option.getRight(Either.left("err")))// Output: { _id: 'Option', _tag: 'None' }liftNullable
Lifts a function that returns null or undefined into the Option
context.
Details
This function takes a function f that might return null or undefined
and transforms it into a function that returns an Option. The resulting
function will return:
Someif the original function produces a non-null, non-undefined value.Noneif the original function producesnullorundefined.
Signature
declare function liftNullable<A extends readonly Array<unknown>, B>(f: (...a: A) => B | null | undefined): (...a: A) => Option<NonNullable<B>>Example
import { Option } from "effect"
const parse = (s: string): number | undefined => { const n = parseFloat(s) return isNaN(n) ? undefined : n}
const parseOption = Option.liftNullable(parse)
console.log(parseOption("1"))// Output: { _id: 'Option', _tag: 'Some', value: 1 }
console.log(parseOption("not a number"))// Output: { _id: 'Option', _tag: 'None' }liftThrowable
Lifts a function that throws exceptions into a function that returns an
Option.
Details
This utility function takes a function f that might throw an exception and
transforms it into a safer function that returns an Option. If the original
function executes successfully, the result is wrapped in a Some. If an
exception is thrown, the result is None, allowing the developer to handle
errors in a functional, type-safe way.
Signature
declare function liftThrowable<A extends readonly Array<unknown>, B>(f: (...a: A) => B): (...a: A) => Option<B>Example
import { Option } from "effect"
const parse = Option.liftThrowable(JSON.parse)
console.log(parse("1"))// Output: { _id: 'Option', _tag: 'Some', value: 1 }
console.log(parse(""))// Output: { _id: 'Option', _tag: 'None' }Converts an Option into an Array.
If the input is None, an empty array is returned.
If the input is Some, its value is wrapped in a single-element array.
Signature
declare function toArray<A>(self: Option<A>): Array<A>Example
import { Option } from "effect"
console.log(Option.toArray(Option.some(1)))// Output: [1]
console.log(Option.toArray(Option.none()))// Output: []toRefinement
Converts an Option-returning function into a type guard.
Details
This function transforms a function that returns an Option into a type
guard, ensuring type safety when validating or narrowing types. The returned
type guard function checks whether the input satisfies the condition defined
in the original Option-returning function.
If the original function returns Option.some, the type guard evaluates to
true, confirming the input is of the desired type. If the function returns
Option.none, the type guard evaluates to false.
This utility is especially useful for validating types in union types, filtering arrays, or ensuring safe handling of specific subtypes.
Signature
declare function toRefinement<A, B>(f: (a: A) => Option<B>): (a: A) => a is BExample
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)
console.log(isString("a"))// Output: true
console.log(isString(1))// Output: falseDo Notation
The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like bind and let.
Here's how the do simulation works:
- Start the do simulation using the
Dovalue - Within the do simulation scope, you can use the
bindfunction to define variables and bind them toOptionvalues - You can accumulate multiple
bindstatements to define multiple variables within the scope - Inside the do simulation scope, you can also use the
letfunction to define variables and bind them to simple values - Regular
Optionfunctions likemapandfiltercan still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
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
import * as assert from "node:assert"import { Option, pipe } from "effect"
const result = 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))assert.deepStrictEqual(result, Option.some({ x: 2, y: 3, sum: 5 }))The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like bind and let.
Here's how the do simulation works:
- Start the do simulation using the
Dovalue - Within the do simulation scope, you can use the
bindfunction to define variables and bind them toOptionvalues - You can accumulate multiple
bindstatements to define multiple variables within the scope - Inside the do simulation scope, you can also use the
letfunction to define variables and bind them to simple values - Regular
Optionfunctions likemapandfiltercan still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
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
import * as assert from "node:assert"import { Option, pipe } from "effect"
const result = 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))assert.deepStrictEqual(result, Option.some({ x: 2, y: 3, sum: 5 }))The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like bind and let.
Here's how the do simulation works:
- Start the do simulation using the
Dovalue - Within the do simulation scope, you can use the
bindfunction to define variables and bind them toOptionvalues - You can accumulate multiple
bindstatements to define multiple variables within the scope - Inside the do simulation scope, you can also use the
letfunction to define variables and bind them to simple values - Regular
Optionfunctions likemapandfiltercan still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
See
Signature
declare const Do: Option<{}>Example
import * as assert from "node:assert"import { Option, pipe } from "effect"
const result = 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))assert.deepStrictEqual(result, Option.some({ x: 2, y: 3, sum: 5 }))Elements
Returns a function that checks if an Option contains a specified value
using the default Equivalence.
Details
This function allows you to check whether an Option contains a specific
value. It uses the default Equivalence for equality comparison. If the
Option is Some and its value is equivalent to the provided value, the
result is true. If the Option is None or the values are not equivalent,
the result is false.
See
- containsWith for a version that allows you to specify a custom equivalence function.
Signature
declare const contains: { <A>(a: A): (self: Option<A>) => boolean; <A>(self: Option<A>, a: A): boolean;}Example
import { Option } from "effect"
console.log(Option.some(2).pipe(Option.contains(2)))// Output: true
console.log(Option.some(1).pipe(Option.contains(2)))// Output: false
console.log(Option.none().pipe(Option.contains(2)))// Output: falsecontainsWith
Returns a function that checks if an Option contains a specified value,
using a provided equivalence function.
Details
This function allows you to check whether an Option contains a specific
value. It uses an equivalence function isEquivalent to compare the value
inside the Option to the provided value. If the Option is Some and the
equivalence function returns true, the result is true. If the Option is
None or the values are not equivalent, the result is false.
See
- contains for a version that uses the default
Equivalence.
Signature
declare function containsWith<A>(isEquivalent: (self: A, that: A) => boolean): { (a: A): (self: Option<A>) => boolean; (self: Option<A>, a: A): boolean;}Example
import { Number, Option } from "effect"
const contains = Option.containsWith(Number.Equivalence)
console.log(Option.some(2).pipe(contains(2)))// Output: true
console.log(Option.some(1).pipe(contains(2)))// Output: false
console.log(Option.none().pipe(contains(2)))// Output: falseChecks if a value in an Option satisfies a given predicate or refinement.
Details
This function allows you to check if a value inside a Some meets a
specified condition. If the Option is None, the result is false. If the
Option is Some, the provided predicate or refinement is applied to the
value:
- If the condition is met, the result is
true. - If the condition is not met, the result is
false.
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
import { Option } from "effect"
const isEven = (n: number) => n % 2 === 0
console.log(Option.some(2).pipe(Option.exists(isEven)))// Output: true
console.log(Option.some(1).pipe(Option.exists(isEven)))// Output: false
console.log(Option.none().pipe(Option.exists(isEven)))// Output: falseEquivalence
getEquivalence
Creates an Equivalence instance for comparing Option values, using a
provided Equivalence for the inner type.
Details
This function takes an Equivalence instance for a specific type A and
produces an Equivalence instance for Option<A>. The resulting
Equivalence determines whether two Option values are equivalent:
- Two
Nones are considered equivalent. - A
Someand aNoneare not equivalent. - Two
Somevalues are equivalent if their inner values are equivalent according to the providedEquivalence.
Signature
declare function getEquivalence<A>(isEquivalent: Equivalence<A>): Equivalence<Option<A>>Example
(Comparing Optional Numbers for Equivalence)
import { Number, Option } from "effect"
const isEquivalent = Option.getEquivalence(Number.Equivalence)
console.log(isEquivalent(Option.none(), Option.none()))// Output: true
console.log(isEquivalent(Option.none(), Option.some(1)))// Output: false
console.log(isEquivalent(Option.some(1), Option.none()))// Output: false
console.log(isEquivalent(Option.some(1), Option.some(2)))// Output: false
console.log(isEquivalent(Option.some(1), Option.some(1)))// Output: trueError Handling
firstSomeOf
Returns the first Some value found in an Iterable collection of
Options, or None if no Some is found.
Details
This function iterates over a collection of Option values and returns the
first Some it encounters. If the collection contains only None values,
the result will also be None. This utility is useful for efficiently
finding the first valid value in a sequence of potentially empty or invalid
options.
The iteration stops as soon as a Some is found, making this function
efficient for large collections.
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
import { Option } from "effect"
console.log(Option.firstSomeOf([ Option.none(), Option.some(1), Option.some(2)]))// Output: { _id: 'Option', _tag: 'Some', value: 1 }Returns the provided Option that if the current Option (self) is
None; otherwise, it returns self.
Details
This function provides a fallback mechanism for Option values. If the
current Option is None (i.e., it contains no value), the that function
is evaluated, and its resulting Option is returned. If the current Option
is Some (i.e., it contains a value), the original Option is returned
unchanged.
This is particularly useful for chaining fallback values or computations,
allowing you to provide alternative Option values when the first one is
empty.
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
import { Option } from "effect"
console.log(Option.none().pipe(Option.orElse(() => Option.none())))// Output: { _id: 'Option', _tag: 'None' }
console.log(Option.some("a").pipe(Option.orElse(() => Option.none())))// Output: { _id: 'Option', _tag: 'Some', value: 'a' }
console.log(Option.none().pipe(Option.orElse(() => Option.some("b"))))// Output: { _id: 'Option', _tag: 'Some', value: 'b' }
console.log(Option.some("a").pipe(Option.orElse(() => Option.some("b"))))// Output: { _id: 'Option', _tag: 'Some', value: 'a' }orElseEither
Similar to orElse, but returns an Either wrapped in an Option to
indicate the source of the value.
Details
This function allows you to provide a fallback Option in case the current
Option (self) is None. However, unlike orElse, it returns the value
wrapped in an Either object, providing additional information about where
the value came from:
- If the value is from the fallback
Option(that), it is wrapped in anEither.right. - If the value is from the original
Option(self), it is wrapped in anEither.left.
This is especially useful when you need to differentiate between values
originating from the primary Option and those coming from the fallback,
while still maintaining the Option-style handling.
Signature
declare const orElseEither: { <B>(that: LazyArg<Option<B>>): <A>(self: Option<A>) => Option<Either<B, A>>; <A, B>(self: Option<A>, that: LazyArg<Option<B>>): Option<Either<B, A>>;}orElseSome
Returns the provided default value wrapped in Some if the current Option
(self) is None; otherwise, returns self.
Details
This function provides a way to supply a default value for cases where an
Option is None. If the current Option is empty (None), the onNone
function is executed to compute the default value, which is then wrapped in a
Some. If the current Option contains a value (Some), it is returned as
is.
This is particularly useful for handling optional values where a fallback default needs to be provided explicitly in case of absence.
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
import { Option } from "effect"
console.log(Option.none().pipe(Option.orElseSome(() => "b")))// Output: { _id: 'Option', _tag: 'Some', value: 'b' }
console.log(Option.some("a").pipe(Option.orElseSome(() => "b")))// Output: { _id: 'Option', _tag: 'Some', value: 'a' }Filtering
Filters an Option using a predicate. If the predicate is not satisfied or the Option is None returns None.
If you need to change the type of the Option in addition to filtering, see filterMap.
Signature
declare const filter: { <A, B>(refinement: Refinement<NoInfer<A>, B>): (self: Option<A>) => Option<B>; <A>(predicate: Predicate<NoInfer<A>>): (self: Option<A>) => Option<A>; <A, B>(self: Option<A>, refinement: Refinement<A, B>): Option<B>; <A>(self: Option<A>, predicate: Predicate<A>): Option<A>;}Example
import { Option } from "effect"
const removeEmptyString = (input: Option.Option<string>) => Option.filter(input, (value) => value !== "")
console.log(removeEmptyString(Option.none()))// Output: { _id: 'Option', _tag: 'None' }
console.log(removeEmptyString(Option.some("")))// Output: { _id: 'Option', _tag: 'None' }
console.log(removeEmptyString(Option.some("a")))// Output: { _id: 'Option', _tag: 'Some', value: 'a' }Alias of flatMap.
Signature
declare const filterMap: { <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
import { Option } from "effect"
// Transform and filter numbersconst transformEven = (n: Option.Option<number>): Option.Option<string> => Option.filterMap(n, (n) => (n % 2 === 0 ? Option.some(`Even: ${n}`) : Option.none()))
console.log(transformEven(Option.none()))// Output: { _id: 'Option', _tag: 'None' }
console.log(transformEven(Option.some(1)))// Output: { _id: 'Option', _tag: 'None' }
console.log(transformEven(Option.some(2)))// Output: { _id: 'Option', _tag: 'Some', value: 'Even: 2' }partitionMap
Splits an Option into two Options based on the result of a mapping
function that produces an Either.
Details
This function takes an Option and a mapping function f that converts its
value into an Either. It returns a tuple of two Options:
- The first
Option(left) contains the value from theLeftside of theEitherif it exists, otherwiseNone. - The second
Option(right) contains the value from theRightside of theEitherif it exists, otherwiseNone.
If the input Option is None, both returned Options are None.
This utility is useful for filtering and categorizing the contents of an
Option based on a bifurcating computation.
Signature
declare const partitionMap: { <A, B, C>(f: (a: A) => Either<C, B>): (self: Option<A>) => [left: Option<B>, right: Option<C>]; <A, B, C>(self: Option<A>, f: (a: A) => Either<C, B>): [left: Option<B>, right: Option<C>];}Generators
Similar to Effect.gen, Option.gen provides a more readable,
generator-based syntax for working with Option values, making code that
involves Option easier to write and understand. This approach is similar to
using async/await but tailored for Option.
Signature
declare const gen: Gen.Gen<OptionTypeLambda, Gen.Adapter<OptionTypeLambda>>Example
import { Option } from "effect"
const maybeName: Option.Option<string> = Option.some("John")const maybeAge: Option.Option<number> = Option.some(25)
const person = Option.gen(function* () { const name = (yield* maybeName).toUpperCase() const age = yield* maybeAge return { name, age }})
console.log(person)// Output:// { _id: 'Option', _tag: 'Some', value: { name: 'JOHN', age: 25 } }Getters
Returns the value contained in the Option if it is Some, otherwise
evaluates and returns the result of onNone.
Details
This function allows you to provide a fallback value or computation for when
an Option is None. If the Option contains a value (Some), that value
is returned. If it is empty (None), the onNone function is executed, and
its result is returned instead.
This utility is helpful for safely handling Option values by ensuring you
always receive a meaningful result, whether or not the Option contains a
value. It is particularly useful for providing default values or alternative
logic when working with optional values.
See
- getOrNull for a version that returns
nullinstead of executing a function. - getOrUndefined for a version that returns
undefinedinstead of executing a function.
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
import { Option } from "effect"
console.log(Option.some(1).pipe(Option.getOrElse(() => 0)))// Output: 1
console.log(Option.none().pipe(Option.getOrElse(() => 0)))// Output: 0Returns the value contained in the Option if it is Some; otherwise,
returns null.
Details
This function provides a way to extract the value of an Option while
falling back to null if the Option is None.
It is particularly useful in scenarios where null is an acceptable
placeholder for the absence of a value, such as when interacting with APIs or
systems that use null as a default for missing values.
Signature
declare const getOrNull: <A>(self: Option<A>) => A | nullExample
import { Option } from "effect"
console.log(Option.getOrNull(Option.some(1)))// Output: 1
console.log(Option.getOrNull(Option.none()))// Output: nullgetOrUndefined
Returns the value contained in the Option if it is Some; otherwise,
returns undefined.
Details
This function provides a way to extract the value of an Option while
falling back to undefined if the Option is None.
It is particularly useful in scenarios where undefined is an acceptable
placeholder for the absence of a value, such as when interacting with APIs or
systems that use undefined as a default for missing values.
Signature
declare const getOrUndefined: <A>(self: Option<A>) => A | undefinedExample
import { Option } from "effect"
console.log(Option.getOrUndefined(Option.some(1)))// Output: 1
console.log(Option.getOrUndefined(Option.none()))// Output: undefinedGuards
Checks whether an Option represents the absence of a value (None).
See
- isSome for the opposite check.
Signature
declare const isNone: <A>(self: Option<A>) => self is None<A>Example
import { Option } from "effect"
console.log(Option.isNone(Option.some(1)))// Output: false
console.log(Option.isNone(Option.none()))// Output: trueDetermines whether the given value is an Option.
Details
This function checks if a value is an instance of Option. It returns true
if the value is either Option.some or Option.none, and false otherwise.
This is particularly useful when working with unknown values or when you need
to ensure type safety in your code.
Signature
declare const isOption: (input: unknown) => input is Option<unknown>Example
import { Option } from "effect"
console.log(Option.isOption(Option.some(1)))// Output: true
console.log(Option.isOption(Option.none()))// Output: true
console.log(Option.isOption({}))// Output: falseSignature
declare const isSome: <A>(self: Option<A>) => self is Some<A>Example
import { Option } from "effect"
console.log(Option.isSome(Option.some(1)))// Output: true
console.log(Option.isSome(Option.none()))// Output: falseLifting
Lifts a binary function to work with Option values, allowing the function
to operate on two Options.
Details
This function takes a binary function f and returns a new function that
applies f to the values of two Options (self and that). If both
Options are Some, the binary function f is applied to their values, and
the result is wrapped in a new Some. If either Option is None, the
result is None.
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
import { Option } from "effect"
// A binary function to add two numbersconst add = (a: number, b: number): number => a + b
// Lift the `add` function to work with `Option` valuesconst addOptions = Option.lift2(add)
// Both `Option`s are `Some`console.log(addOptions(Option.some(2), Option.some(3)))// Output: { _id: 'Option', _tag: 'Some', value: 5 }
// One `Option` is `None`console.log(addOptions(Option.some(2), Option.none()))// Output: { _id: 'Option', _tag: 'None' }liftPredicate
Lifts a Predicate or Refinement into the Option context, returning a
Some of the input value if the predicate is satisfied, or None otherwise.
Details
This function transforms a Predicate (or a more specific Refinement) into
a function that produces an Option. If the predicate evaluates to true,
the input value is wrapped in a Some. If the predicate evaluates to
false, the result is None.
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
import { Option } from "effect"
// Check if a number is positiveconst isPositive = (n: number) => n > 0
// ┌─── (b: number) => Option<number>// ▼const parsePositive = Option.liftPredicate(isPositive)
console.log(parsePositive(1))// Output: { _id: 'Option', _tag: 'Some', value: 1 }
console.log(parsePositive(-1))// OUtput: { _id: 'Option', _tag: 'None' }Mapping
Replaces the value inside a Some with the specified constant value, leaving
None unchanged.
Details
This function transforms an Option by replacing the value inside a Some
with the given constant value b. If the Option is None, it remains
unchanged.
This is useful when you want to preserve the presence of a value (Some) but
replace its content with a fixed value.
Signature
declare const as: { <B>(b: B): <X>(self: Option<X>) => Option<B>; <X, B>(self: Option<X>, b: B): Option<B>;}Example
import { Option } from "effect"
// Replacing the value of a `Some`const someValue = Option.some(42)
console.log(Option.as(someValue, "new value"))// Output: { _id: 'Option', _tag: 'Some', value: 'new value' }
// Replacing a `None` (no effect)const noneValue = Option.none<number>()
console.log(Option.as(noneValue, "new value"))// Output: { _id: 'Option', _tag: 'None' }Replaces the value inside a Some with the constant value void, leaving
None unchanged.
Details
This function transforms an Option by replacing the value inside a Some
with void. If the Option is None, it remains unchanged.
This is particularly useful in scenarios where the presence or absence of a value is significant, but the actual content of the value is irrelevant.
Signature
declare const asVoid: <_>(self: Option<_>) => Option<void>Transforms the value inside a Some to a new value using the provided
function, while leaving None unchanged.
Details
This function applies a mapping function f to the value inside an Option
if it is a Some. If the Option is None, it remains unchanged. The
result is a new Option with the transformed value (if it was a Some) or
still None.
This utility is particularly useful for chaining transformations in a
functional way without needing to manually handle None cases.
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
import { Option } from "effect"
// Mapping over a `Some`const someValue = Option.some(2)
console.log(Option.map(someValue, (n) => n * 2))// Output: { _id: 'Option', _tag: 'Some', value: 4 }
// Mapping over a `None`const noneValue = Option.none<number>()
console.log(Option.map(noneValue, (n) => n * 2))// Output: { _id: 'Option', _tag: 'None' }Models
Signature
interface None<out A> extends Pipeable, Inspectable, STM<A, Cause.NoSuchElementException>, Effect<A, Cause.NoSuchElementException> { readonly _op: "None"; readonly _tag: "None"; readonly [ChannelTypeId]: VarianceStruct<never, unknown, NoSuchElementException, unknown, A, unknown, never>; readonly [EffectTypeId]: VarianceStruct<A, NoSuchElementException, never>; [ignoreSymbol]?: OptionUnifyIgnore; readonly [SinkTypeId]: VarianceStruct<A, unknown, never, NoSuchElementException, never>; readonly [STMTypeId]: { readonly _A: Covariant<A>; readonly _E: Covariant<NoSuchElementException>; readonly _R: Covariant<never>; }; readonly [StreamTypeId]: VarianceStruct<A, NoSuchElementException, never>; readonly [TypeId]: { readonly _A: Covariant<A>; }; [typeSymbol]?: unknown; [unifySymbol]?: OptionUnify<None<A>>; [iterator](): EffectGenerator<None<A>>;}The Option data type represents optional values. An Option<A> can either
be Some<A>, containing a value of type A, or None, representing the
absence of a value.
When to Use
You can use Option in scenarios like:
- Using it for initial values
- Returning values from functions that are not defined for all possible inputs (referred to as “partial functions”)
- Managing optional fields in data structures
- Handling optional function arguments
Signature
type Option<A> = None<A> | Some<A>OptionUnify interface
Signature
interface OptionUnify<A extends { [typeSymbol]?: any;}> { Option?: () => A[typeof typeSymbol] extends Option<A0> | _ ? Option<A0> : never;}OptionUnifyIgnore interface
Signature
interface OptionUnifyIgnore { Effect?: true; Either?: true; Tag?: true;}Signature
interface Some<out A> extends Pipeable, Inspectable, STM<A, Cause.NoSuchElementException>, Effect<A, Cause.NoSuchElementException> { readonly _op: "Some"; readonly _tag: "Some"; readonly [ChannelTypeId]: VarianceStruct<never, unknown, NoSuchElementException, unknown, A, unknown, never>; readonly [EffectTypeId]: VarianceStruct<A, NoSuchElementException, never>; [ignoreSymbol]?: OptionUnifyIgnore; readonly [SinkTypeId]: VarianceStruct<A, unknown, never, NoSuchElementException, never>; readonly [STMTypeId]: { readonly _A: Covariant<A>; readonly _E: Covariant<NoSuchElementException>; readonly _R: Covariant<never>; }; readonly [StreamTypeId]: VarianceStruct<A, NoSuchElementException, never>; readonly [TypeId]: { readonly _A: Covariant<A>; }; [typeSymbol]?: unknown; [unifySymbol]?: OptionUnify<Some<A>>; readonly value: A; [iterator](): EffectGenerator<Some<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 }>;}Signature
declare const void: Option<void>Pattern Matching
Performs pattern matching on an Option to handle both Some and None
cases.
Details
This function allows you to match against an Option and handle both
scenarios: when the Option is None (i.e., contains no value), and when
the Option is Some (i.e., contains a value). It executes one of the
provided functions based on the case:
- If the
OptionisNone, theonNonefunction is executed and its result is returned. - If the
OptionisSome, theonSomefunction is executed with the contained value, and its result is returned.
This function provides a concise and functional way to handle optional values
without resorting to if or manual checks, making your code more declarative
and readable.
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
(Pattern Matching with Option)
import { Option } from "effect"
const foo = Option.some(1)
const message = Option.match(foo, { onNone: () => "Option is empty", onSome: (value) => `Option has a value: ${value}`})
console.log(message)// Output: "Option has a value: 1"Reducing
reduceCompact
Reduces an Iterable of Option<A> to a single value of type B, ignoring
elements that are None.
Details
This function takes an initial value of type B and a reducing function f
that combines the accumulator with values of type A. It processes an
iterable of Option<A>, applying f only to the Some values while
ignoring the None values. The result is a single value of type B.
This utility is particularly useful for aggregating values from an iterable
of Options while skipping the absent (None) values.
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
import { Option, pipe } from "effect"
const iterable = [Option.some(1), Option.none(), Option.some(2), Option.none()]
console.log(pipe(iterable, Option.reduceCompact(0, (b, a) => b + a)))// Output: 3Sequencing
Chains two Options together. The second Option can either be a static
value or depend on the result of the first Option.
Details
This function enables sequencing of two Option computations. If the first
Option is Some, the second Option is evaluated. The second Option can
either:
- Be a static
Optionvalue. - Be a function that produces an
Option, optionally based on the value of the firstOption.
If the first Option is None, the function skips the evaluation of the
second Option and directly returns None.
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>;}Composes two functions that return Option values, creating a new function
that chains them together.
Details
This function allows you to compose two computations, each represented by a
function that returns an Option. The result of the first function is passed
to the second function if it is Some. If the first function returns None,
the composed function short-circuits and returns None without invoking the
second function.
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
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)
console.log(parseAndDouble("42"))// Output: { _id: 'Option', _tag: 'Some', value: 84 }
console.log(parseAndDouble("not a number"))// Output: { _id: 'Option', _tag: 'None' }Applies a function to the value of a Some and flattens the resulting
Option. If the input is None, it remains None.
Details
This function allows you to chain computations that return Option values.
If the input Option is Some, the provided function f is applied to the
contained value, and the resulting Option is returned. If the input is
None, the function is not applied, and the result remains None.
This utility is particularly useful for sequencing operations that may fail or produce optional results, enabling clean and concise workflows for handling such cases.
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
import { Option } from "effect"
interface Address { readonly city: string readonly street: Option.Option<string>}
interface User { readonly id: number readonly username: string readonly email: Option.Option<string> readonly address: Option.Option<Address>}
const user: User = { id: 1, username: "john_doe", email: Option.some("john.doe@example.com"), address: Option.some({ city: "New York", street: Option.some("123 Main St") })}
// Use flatMap to extract the street valueconst street = user.address.pipe( Option.flatMap((address) => address.street))
console.log(street)// Output: { _id: 'Option', _tag: 'Some', value: '123 Main St' }flatMapNullable
Combines flatMap and fromNullable, transforming the value inside a Some
using a function that may return null or undefined.
Details
This function applies a transformation function f to the value inside a
Some. The function f may return a value, null, or undefined. If f
returns a value, it is wrapped in a Some. If f returns null or
undefined, the result is None. If the input Option is None, the
function is not applied, and None is returned.
This utility is particularly useful when working with deeply nested optional
values or chaining computations that may result in null or undefined at
some point.
Signature
declare const flatMapNullable: { <A, B>(f: (a: A) => B | null | undefined): (self: Option<A>) => Option<NonNullable<B>>; <A, B>(self: Option<A>, f: (a: A) => B | null | undefined): Option<NonNullable<B>>;}Example
import { Option } from "effect"
interface Employee { company?: { address?: { street?: { name?: string } } }}
const employee1: Employee = { company: { address: { street: { name: "high street" } } } }
// Extracting a deeply nested propertyconsole.log( Option.some(employee1) .pipe(Option.flatMapNullable((employee) => employee.company?.address?.street?.name)))// Output: { _id: 'Option', _tag: 'Some', value: 'high street' }
const employee2: Employee = { company: { address: { street: {} } } }
// Property does not existconsole.log( Option.some(employee2) .pipe(Option.flatMapNullable((employee) => employee.company?.address?.street?.name)))// Output: { _id: 'Option', _tag: 'None' }Flattens an Option of Option into a single Option.
Details
This function takes an Option that wraps another Option and flattens it
into a single Option. If the outer Option is Some, the function
extracts the inner Option. If the outer Option is None, the result
remains None.
This is useful for simplifying nested Option structures that may arise
during functional operations.
Signature
declare const flatten: <A>(self: Option<Option<A>>) => Option<A>Applies the provided function f to the value of the Option if it is
Some and returns the original Option, unless f returns None, in which
case it returns None.
Details
This function allows you to perform additional computations on the value of
an Option without modifying its original value. If the Option is Some,
the provided function f is executed with the value, and its result
determines whether the original Option is returned (Some) or the result
is None if f returns None. If the input Option is None, the
function is not executed, and None is returned.
This is particularly useful for applying side conditions or performing
validation checks while retaining the original Option's value.
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
import { Option } from "effect"
const getInteger = (n: number) => Number.isInteger(n) ? Option.some(n) : Option.none()
console.log(Option.tap(Option.none(), getInteger))// Output: { _id: 'Option', _tag: 'None' }
console.log(Option.tap(Option.some(1), getInteger))// Output: { _id: 'Option', _tag: 'Some', value: 1 }
console.log(Option.tap(Option.some(1.14), getInteger))// Output: { _id: 'Option', _tag: 'None' }Sorting
Creates an Order instance for comparing Option values, using a provided
Order for the inner type.
Details
This function produces an Order instance for Option<A>, allowing Option
values to be compared:
Noneis always considered less than anySomevalue.- If both are
Some, their inner values are compared using the providedOrderinstance.
Signature
declare function getOrder<A>(O: Order<A>): Order<Option<A>>Example
import { Number, Option } from "effect"
const order = Option.getOrder(Number.Order)
console.log(order(Option.none(), Option.none()))// Output: 0
console.log(order(Option.none(), Option.some(1)))// Output: -1
console.log(order(Option.some(1), Option.none()))// Output: 1
console.log(order(Option.some(1), Option.some(2)))// Output: -1
console.log(order(Option.some(1), Option.some(1)))// Output: 0Symbols
Type Lambdas
OptionTypeLambda interface
Signature
interface OptionTypeLambda extends TypeLambda { readonly type: Option<unknown>;}Zipping
Combines two Options, keeping the value from the first Option if both are
Some.
Details
This function takes two Options and returns the first one if it is Some.
If either the first Option or the second Option is None, the result
will be None. This operation "zips" the two Options while discarding the
value from the second Option.
This is useful when sequencing computations where the second Option
represents a dependency or condition that must hold, but its value is
irrelevant.
Signature
declare const zipLeft: { <_>(that: Option<_>): <A>(self: Option<A>) => Option<A>; <A, X>(self: Option<A>, that: Option<X>): Option<A>;}Combines two Options, keeping the value from the second Option if both
are Some.
Details
This function takes two Options and returns the second one if the first is
Some. If the first Option is None, the result will also be None,
regardless of the second Option. It effectively "zips" the two Options
while discarding the value from the first Option.
This is particularly useful when sequencing computations where the result of the first computation is not needed, and you only care about the result of the second computation.
Signature
declare const zipRight: { <B>(that: Option<B>): <_>(self: Option<_>) => Option<B>; <X, B>(self: Option<X>, that: Option<B>): Option<B>;}Combines two Option values into a new Option by applying a provided
function to their values.
Details
This function takes two Option values (self and that) and a combining
function f. If both Option values are Some, the function f is applied
to their values, and the result is wrapped in a new Some. If either
Option is None, the result is None.
This utility is useful for combining two optional computations into a single
result while maintaining type safety and avoiding explicit checks for None.
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
import { Option } from "effect"
const maybeName: Option.Option<string> = Option.some("John")const maybeAge: Option.Option<number> = Option.some(25)
// Combine the name and age into a person objectconst person = Option.zipWith(maybeName, maybeAge, (name, age) => ({ name: name.toUpperCase(), age}))
console.log(person)// Output:// { _id: 'Option', _tag: 'Some', value: { name: 'JOHN', age: 25 } }