Result.ts
Result.ts overview
Section titled “Result.ts overview”Models a value that has already succeeded or failed.
A Result<A, E> is Success<A, E> when a value is available and
Failure<A, E> when an error is available. It is plain data, so inspecting
or transforming it does not run side effects. This module includes helpers
for creating, checking, mapping, combining, and extracting results, plus
conversions to and from Option and nullable values.
Since v4.0.0
Exports Grouped by Category
Section titled “Exports Grouped by Category”- Transposing
- constructors
- do notation
- error handling
- filtering
- generators
- getters
- guards
- instances
- mapping
- models
- pattern matching
- sequencing
- transforming
- type lambdas
- utils
Transposing
Section titled “Transposing”transposeMapOption
Section titled “transposeMapOption”Maps an Option value with a Result-producing function, then transposes
the structure from Option<Result<B, E>> to Result<Option<B>, E>.
When to use
Use when an optional value should be validated only when present, preserving
absence as a successful None.
Details
NonebecomesSuccess(None)(the function is never called)Some(a)wheref(a)isSuccess(b)becomesSuccess(Some(b))Some(a)wheref(a)isFailure(e)becomesFailure(e)
Example (Mapping and transposing in one step)
import { Option, Result } from "effect"
const parse = (s: string) => (isNaN(Number(s)) ? Result.fail("not a number" as const) : Result.succeed(Number(s)))
console.log(Result.transposeMapOption(Option.some("42"), parse))// Output: { _tag: "Success", success: { _tag: "Some", value: 42 }, ... }
console.log(Result.transposeMapOption(Option.none(), parse))// Output: { _tag: "Success", success: { _tag: "None" }, ... }See
transposeOptionwhen the Option already contains a Result
Signature
declare const transposeMapOption: (<A, B, E = never>( f: (self: A) => Result<B, E>) => (self: Option<A>) => Result<Option<B>, E>) & (<A, B, E = never>(self: Option<A>, f: (self: A) => Result<B, E>) => Result<Option<B>, E>)Since v3.15.0
transposeOption
Section titled “transposeOption”Transforms Option<Result<A, E>> into Result<Option<A>, E>.
When to use
Use when optional absence should be treated as a successful None, while an
inner Result failure should still fail the whole result.
Details
NonebecomesSuccess(None)Some(Success(a))becomesSuccess(Some(a))Some(Failure(e))becomesFailure(e)
Example (Transposing an Option of a Result)
import { Option, Result } from "effect"
const some = Option.some(Result.succeed(42))console.log(Result.transposeOption(some))// Output: { _tag: "Success", success: { _tag: "Some", value: 42 }, ... }
const none = Option.none<Result.Result<number, string>>()console.log(Result.transposeOption(none))// Output: { _tag: "Success", success: { _tag: "None" }, ... }See
transposeMapOptionto map and transpose in one step
Signature
declare const transposeOption: <A = never, E = never>(self: Option<Result<A, E>>) => Result<Option<A>, E>Since v3.14.0
constructors
Section titled “constructors”Creates a Result holding a Failure value.
When to use
Use to represent a failed Result with a typed failure value.
Details
- The success type
Adefaults tonever
Example (Creating a failure)
import { Result } from "effect"
const result = Result.fail("Something went wrong")
console.log(Result.isFailure(result))// Output: trueSee
succeedto create a SuccessmapErrorto transform the error
Signature
declare const fail: <E>(left: E) => Result<never, E>Since v4.0.0
failVoid
Section titled “failVoid”Provides a pre-built failed Result whose failure value is undefined.
When to use
Use when you need a failed Result value that acts only as a control signal
without failure data.
Details
This is equivalent to Result.fail(undefined) with type
Result<never, void>, but reuses a shared Failure wrapper instead of
allocating one each time.
Example (Failing without a payload)
import { Result } from "effect"
const result = Result.failVoid
console.log(Result.isFailure(result))// Output: trueSee
failto create a Failure with a specific value
Signature
declare const failVoid: Result<never, void>Since v4.0.0
fromNullishOr
Section titled “fromNullishOr”Converts a possibly null or undefined value into a Result.
When to use
Use when you need null or undefined input to become a Failure while
present values remain available as Success.
Details
- Non-nullish values become
Success<NonNullable<A>> nullorundefinedbecomesFailure<E>using the provided function- Supports both data-first and data-last (piped) usage
- The
onNullishcallback receives the original value
Example (Handling nullable values)
import { Result } from "effect"
console.log(Result.fromNullishOr(1, () => "fallback"))// Output: { _tag: "Success", success: 1, ... }
console.log(Result.fromNullishOr(null, () => "fallback"))// Output: { _tag: "Failure", failure: "fallback", ... }See
fromOptionto convert from an Optionsucceed/failfor direct construction
Signature
declare const fromNullishOr: { <A, E>(onNullish: (a: A) => E): (self: A) => Result<NonNullable<A>, E> <A, E>(self: A, onNullish: (a: A) => E): Result<NonNullable<A>, E>}Since v4.0.0
fromOption
Section titled “fromOption”Converts an Option<A> into a Result<A, E>.
When to use
Use when an existing Option should become a Result, preserving Some as
success and turning None into a caller-provided failure.
Details
Some<A>becomesSuccess<A>NonebecomesFailure<E>using the provided function- Supports both data-first and data-last (piped) usage
Example (Converting an Option to a Result)
import { Option, Result } from "effect"
const some = Result.fromOption(Option.some(1), () => "missing")console.log(some)// Output: { _tag: "Success", success: 1, ... }
const none = Result.fromOption(Option.none(), () => "missing")console.log(none)// Output: { _tag: "Failure", failure: "missing", ... }See
getSuccessto extract the success value as an OptiongetFailureto extract the failure value as an OptionfromNullishOrto build a Result from nullable values
Signature
declare const fromOption: { <E>(onNone: () => E): <A>(self: Option<A>) => Result<A, E> <A, E>(self: Option<A>, onNone: () => E): Result<A, E>}Since v2.0.0
liftPredicate
Section titled “liftPredicate”Lifts a value into a Result based on a predicate or refinement.
When to use
Use to construct a Result from a raw value guarded by a predicate or
refinement.
Details
- If the predicate returns
true, the value becomesSuccess<A> - If the predicate returns
false,orFailWithproduces the error forFailure<E> - Also accepts a
Refinementto narrow the success type - Supports both data-first and data-last (piped) usage
Example (Validating a number)
import { pipe, Result } from "effect"
const ensurePositive = pipe( 5, Result.liftPredicate( (n: number) => n > 0, (n) => `${n} is not positive` ))console.log(ensurePositive)// Output: { _tag: "Success", success: 5, ... }See
filterOrFailto validate a value that is already in aResultfromNullishOrfor nullable-based construction
Signature
declare const liftPredicate: { <A, B extends A, E>(refinement: Refinement<A, B>, orFailWith: (a: A) => E): (a: A) => Result<B, E> <B extends A, E, A = B>(predicate: Predicate<A>, orFailWith: (a: A) => E): (a: B) => Result<B, E> <A, E, B extends A>(self: A, refinement: Refinement<A, B>, orFailWith: (a: A) => E): Result<B, E> <B extends A, E, A = B>(self: B, predicate: Predicate<A>, orFailWith: (a: A) => E): Result<B, E>}Since v3.4.0
succeed
Section titled “succeed”Creates a Result holding a Success value.
Details
- Use when you have a value and want to lift it into the
Resulttype - The error type
Edefaults tonever
Example (Wrapping a value)
import { Result } from "effect"
const result = Result.succeed(42)
console.log(Result.isSuccess(result))// Output: trueSee
failto create a Failurevoidfor a pre-builtSuccess<void>
Signature
declare const succeed: <A>(right: A) => Result<A>Since v4.0.0
succeedNone
Section titled “succeedNone”Provides a pre-built Result<Option<never>> that succeeds with None.
When to use
Use when an optional success should be absent, such as the None branch of
transposeOption or transposeMapOption.
Details
This is equivalent to Result.succeed(Option.none()), but reuses a shared
Success wrapper instead of allocating one each time.
Example (Succeeding with None)
import { Result } from "effect"
console.log(Result.isSuccess(Result.succeedNone))// Output: trueSee
succeedSomefor theSomecounterparttransposeOptionto transpose an Option that already contains a ResulttransposeMapOptionto map and transpose an Option in one step
Signature
declare const succeedNone: Result<Option<never>, never>Since v4.0.0
succeedSome
Section titled “succeedSome”Creates a Result<Option<A>> that succeeds with Some(a).
Details
- Equivalent to
Result.succeed(Option.some(a)) - Useful with
transposeOptionpatterns
Example (Wrapping a value in Some inside a Result)
import { Result } from "effect"
const result = Result.succeedSome(42)console.log(result)// Output: { _tag: "Success", success: { _tag: "Some", value: 42 }, ... }See
succeedNonefor theNonecounterpart
Signature
declare const succeedSome: <A, E = never>(a: A) => Result<Option<A>, E>Since v4.0.0
Wraps a synchronous computation that may throw into a Result safely.
Details
- If the function returns normally, the result is
Success<A> - If the function throws, the exception is caught and becomes
Failure<E> - With a single function argument, the error type is
unknown - With
{ try, catch }options, thecatchfunction maps the thrown value toE
Example (Catching JSON parse errors)
import { Result } from "effect"
const ok = Result.try(() => JSON.parse('{"name": "Alice"}'))console.log(ok)// Output: { _tag: "Success", success: { name: "Alice" }, ... }
const err = Result.try({ try: () => JSON.parse("not json"), catch: (e) => `Parse failed: ${e}`})console.log(Result.isFailure(err))// Output: trueSee
succeed/failfor direct constructionfromNullishOrfor nullable values
Signature
declare const try: { <A, E>(options: { readonly try: LazyArg<A>; readonly catch: (error: unknown) => E; }): Result<A, E>; <A>(evaluate: LazyArg<A>): Result<A, unknown>; }Since v2.0.0
Provides a pre-built successful Result that carries undefined.
When to use
Use when you need a successful Result value that signals completion
without carrying meaningful data.
Details
This is equivalent to Result.succeed(undefined), but reuses a shared
Success wrapper instead of allocating one each time.
Example (Referencing void results)
import { Result } from "effect"
const result: Result.Result<void> = Result.void
console.log(Result.isSuccess(result))// Output: trueSee
succeedto create a Success with a specific value
Signature
declare const void: Result<void, never>Since v3.13.0
do notation
Section titled “do notation”Provides the starting point for the “do notation” simulation with Result.
When to use
Use to start a Result do-notation pipeline from an empty successful record
before adding named fields from Result-producing computations and pure
computed values.
Details
Creates a Result<{}> (success with an empty object). Use with
bind to add Result-producing fields and let
to add pure computed fields.
Example (Building an object step by step)
import { pipe, Result } from "effect"
const result = pipe( Result.Do, Result.bind("x", () => Result.succeed(2)), Result.bind("y", () => Result.succeed(3)), Result.let("sum", ({ x, y }) => x + y))console.log(result)// Output: { _tag: "Success", success: { x: 2, y: 3, sum: 5 }, ... }See
bindto add Result-producing fieldsletto add pure computed fieldsgenfor an alternative generator-based syntaxbindTofor starting a do-notation chain from an existing Result
Signature
declare const Do: Result<{}, never>Since v2.0.0
Adds a named field to the do-notation accumulator by running a Result-producing
function that receives the current accumulated object.
When to use
Use when you need to add a Result-producing step to a Result
do-notation pipeline and store its successful value under a named field in
the accumulated object.
Details
- Short-circuits on the first
Failure - The field name must not collide with existing keys
- Use
letfor pure (non-Result) computed fields
Example (Binding Result values)
import { pipe, Result } from "effect"
const result = pipe( Result.Do, Result.bind("x", () => Result.succeed(2)), Result.bind("y", ({ x }) => Result.succeed(x + 3)))console.log(result)// Output: { _tag: "Success", success: { x: 2, y: 5 }, ... }See
Doto start the do-notation chainletfor pure computed fieldsbindToto wrap an initial Result into a named field
Signature
declare const bind: { <N extends string, A extends object, B, L2>( name: Exclude<N, keyof A>, f: (a: NoInfer<A>) => Result<B, L2> ): <L1>(self: Result<A, L1>) => Result<{ [K in N | keyof A]: K extends keyof A ? A[K] : B }, L1 | L2> <A extends object, L1, N extends string, B, L2>( self: Result<A, L1>, name: Exclude<N, keyof A>, f: (a: NoInfer<A>) => Result<B, L2> ): Result<{ [K in N | keyof A]: K extends keyof A ? A[K] : B }, L1 | L2>}Since v2.0.0
bindTo
Section titled “bindTo”Wraps the success value of a Result into a named field, producing a
Result<Record<N, A>>.
When to use
Use to name the success value of an existing Result before continuing a
do-notation pipeline.
Details
This is typically used to start a do-notation chain from an existing
Result.
Example (Wrapping a value into a named field)
import { pipe, Result } from "effect"
const result = pipe(Result.succeed(42), Result.bindTo("answer"))console.log(result)// Output: { _tag: "Success", success: { answer: 42 }, ... }See
Doto start from an empty objectbindto add more fields
Signature
declare const bindTo: { <N extends string>(name: N): <R, L>(self: Result<R, L>) => Result<Record<N, R>, L> <R, L, N extends string>(self: Result<R, L>, name: N): Result<Record<N, R>, L>}Since v2.0.0
Adds a named field to the do-notation accumulator by computing a pure (non-Result) value from the current accumulated object.
When to use
Use when you need to add a derived field that cannot fail inside a do-notation pipeline.
Details
- Use
bindwhen the computation returns aResult - The field name must not collide with existing keys
Example (Adding a computed field)
import { pipe, Result } from "effect"
const result = pipe( Result.Do, Result.bind("x", () => Result.succeed(2)), Result.bind("y", () => Result.succeed(3)), Result.let("sum", ({ x, y }) => x + y))console.log(result)// Output: { _tag: "Success", success: { x: 2, y: 3, sum: 5 }, ... }See
Doto start the do-notation chainbindfor Result-producing fields
Signature
declare const let: { <N extends string, R extends object, B>( name: Exclude<N, keyof R>, f: (r: NoInfer<R>) => B ): <L>(self: Result<R, L>) => Result<{ [K in N | keyof R]: K extends keyof R ? R[K] : B }, L> <R extends object, L, N extends string, B>( self: Result<R, L>, name: Exclude<N, keyof R>, f: (r: NoInfer<R>) => B ): Result<{ [K in N | keyof R]: K extends keyof R ? R[K] : B }, L>}Since v2.0.0
error handling
Section titled “error handling”orElse
Section titled “orElse”Returns the original Result if it is a Success, otherwise applies
that to the error and returns the resulting Result.
When to use
Use when a failure should recover into another Result while keeping
successes unchanged.
Details
Success<A>is returned unchangedFailure<E>callsthat(e)to produce a newResult
Example (Recovering from a failure)
import { pipe, Result } from "effect"
const result = pipe( Result.fail("primary failed"), Result.orElse(() => Result.succeed(99)))console.log(result)// Output: { _tag: "Success", success: 99, ... }See
getOrElseto unwrap with a fallback value (not a Result)mapErrorto transform the error without recovering
Signature
declare const orElse: { <E, A2, E2>(that: (err: E) => Result<A2, E2>): <A>(self: Result<A, E>) => Result<A | A2, E2> <A, E, A2, E2>(self: Result<A, E>, that: (err: E) => Result<A2, E2>): Result<A | A2, E2>}Since v2.0.0
filtering
Section titled “filtering”filterOrFail
Section titled “filterOrFail”Validates the success value of a Result using a predicate, failing with a
custom error if the predicate returns false.
When to use
Use to validate an already-successful Result value with a predicate or
refinement.
Details
- If the result is already a
Failure, it is returned as-is - If the predicate passes, the
Successis returned unchanged - If the predicate fails,
orFailWithproduces the error for a newFailure - Also accepts a
Refinementto narrow the success type - The error type of the output is the union of both error types
Example (Filtering a success value)
import { pipe, Result } from "effect"
const result = pipe( Result.succeed(0), Result.filterOrFail( (n) => n > 0, (n) => `${n} is not positive` ))console.log(result)// Output: { _tag: "Failure", failure: "0 is not positive", ... }See
liftPredicateto create aResultfrom a raw value with a predicateflatMapfor general conditional chaining
Signature
declare const filterOrFail: { <A, B extends A, E2>( refinement: Refinement<NoInfer<A>, B>, orFailWith: (value: NoInfer<A>) => E2 ): <E>(self: Result<A, E>) => Result<B, E2 | E> <A, E2>( predicate: Predicate<NoInfer<A>>, orFailWith: (value: NoInfer<A>) => E2 ): <E>(self: Result<A, E>) => Result<A, E2 | E> <A, E, B extends A, E2>( self: Result<A, E>, refinement: Refinement<A, B>, orFailWith: (value: A) => E2 ): Result<B, E | E2> <A, E, E2>(self: Result<A, E>, predicate: Predicate<A>, orFailWith: (value: A) => E2): Result<A, E | E2>}Since v4.0.0
generators
Section titled “generators”ResultIterator (interface)
Section titled “ResultIterator (interface)”Iterator protocol used to yield a Result inside gen, returning the
success value type back to the generator.
When to use
Use when defining or typing [Symbol.iterator]() for Result values so
yield* can pass the success value type back into Result.gen.
See
genfor writing generator-basedResultcode that consumes this iterator protocol
Signature
export interface ResultIterator<T extends Result<any, any>> { next(...args: ReadonlyArray<any>): IteratorResult<T, Result.Success<T>>}Since v4.0.0
Provides generator-based syntax for composing Result values sequentially.
When to use
Use when you need generator syntax to compose sequential Result
computations instead of nested flatMap calls.
Details
- Use
yield*to unwrap aResultinside the generator; if any yieldedResultis aFailure, the generator short-circuits and returns that failure - The return value of the generator is wrapped in
Success - Evaluated eagerly and synchronously (unlike
Effect.gen)
Example (Composing multiple Results)
import { Result } from "effect"
const result = Result.gen(function* () { const a = yield* Result.succeed(1) const b = yield* Result.succeed(2) return a + b})
console.log(result)// Output: { _tag: "Success", success: 3, ... }See
flatMapfor point-free sequential compositionallto collect multiple independent Results
Signature
declare const gen: Gen.Gen<ResultTypeLambda>Since v2.0.0
getters
Section titled “getters”getFailure
Section titled “getFailure”Extracts the failure value as an Option, discarding the success.
When to use
Use when you need to extract the failure value from a Result as an
Option and discard successful values.
Details
Failure<E>becomesSome<E>Success<A>becomesNone
Example (Extracting the failure as an Option)
import { Option, Result } from "effect"
console.log(Result.getFailure(Result.succeed("ok")))// Output: { _tag: "None" }
console.log(Result.getFailure(Result.fail("err")))// Output: { _tag: "Some", value: "err" }See
getSuccessto extract the success insteadfromOptionfor the reverse conversion
Signature
declare const getFailure: <A, E>(self: Result<A, E>) => Option<E>Since v4.0.0
getOrElse
Section titled “getOrElse”Extracts the success value, or computes a fallback from the error.
When to use
Use when you need the success value from a Result, with a fallback computed
from the failure value.
Details
Success<A>returns the inner valueFailure<E>appliesonFailureto the error and returns the result- The return type is
A | A2(union of both branches)
Example (Providing a fallback)
import { Result } from "effect"
console.log(Result.getOrElse(Result.succeed(1), () => 0))// Output: 1
console.log(Result.getOrElse(Result.fail("err"), () => 0))// Output: 0See
getOrNull/getOrUndefinedfor simpler fallbacksgetOrThrowto throw on failurematchto map both branchesorElseto recover with another Result instead of unwrapping
Signature
declare const getOrElse: { <E, A2>(onFailure: (err: E) => A2): <A>(self: Result<A, E>) => A2 | A <A, E, A2>(self: Result<A, E>, onFailure: (err: E) => A2): A | A2}Since v2.0.0
getOrNull
Section titled “getOrNull”Extracts the success value, or returns null on failure.
When to use
Use when you need to pass failed Result values to APIs that represent
absence as null.
Details
Success<A>returnsAFailure<E>returnsnull
Example (Unwrapping to nullable)
import { Result } from "effect"
console.log(Result.getOrNull(Result.succeed(1)))// Output: 1
console.log(Result.getOrNull(Result.fail("err")))// Output: nullSee
getOrUndefinedto returnundefinedinsteadgetOrElsefor a custom fallback
Signature
declare const getOrNull: <A, E>(self: Result<A, E>) => A | nullSince v2.0.0
getOrThrow
Section titled “getOrThrow”Extracts the success value or throws the raw failure value E.
When to use
Use when unchecked boundaries should turn failures into thrown exceptions.
Details
Success<A>returnsAFailure<E>throwsEdirectly- Use
getOrThrowWithfor a custom error object
Example (Unwrapping or throwing)
import { Result } from "effect"
console.log(Result.getOrThrow(Result.succeed(1)))// Output: 1
// This would throw the string "error":// Result.getOrThrow(Result.fail("error"))See
getOrThrowWithfor custom error mappinggetOrElsefor a non-throwing alternative
Signature
declare const getOrThrow: <A, E>(self: Result<A, E>) => ASince v2.0.0
getOrThrowWith
Section titled “getOrThrowWith”Extracts the success value or throws a custom error derived from the failure.
When to use
Use when converting a Result into a thrown exception with a custom error
message or error type.
Details
Success<A>returnsAFailure<E>throws the value returned byonFailure(e)
Example (Throwing a custom error)
import { Result } from "effect"
console.log(Result.getOrThrowWith(Result.succeed(1), () => new Error("fail")))// Output: 1
// This would throw: new Error("Unexpected: oops")// Result.getOrThrowWith(// Result.fail("oops"),// (err) => new Error(`Unexpected: ${err}`)// )See
getOrThrowto throw the raw failure valuegetOrElsefor a non-throwing alternative
Signature
declare const getOrThrowWith: { <E>(onFailure: (err: E) => unknown): <A>(self: Result<A, E>) => A <A, E>(self: Result<A, E>, onFailure: (err: E) => unknown): A}Since v2.0.0
getOrUndefined
Section titled “getOrUndefined”Extracts the success value, or returns undefined on failure.
When to use
Use when you need to pass failed Result values to APIs that represent
absence as undefined.
Details
Success<A>returnsAFailure<E>returnsundefined
Example (Unwrapping to optional)
import { Result } from "effect"
console.log(Result.getOrUndefined(Result.succeed(1)))// Output: 1
console.log(Result.getOrUndefined(Result.fail("err")))// Output: undefinedSee
getOrNullto returnnullinsteadgetOrElsefor a custom fallback
Signature
declare const getOrUndefined: <A, E>(self: Result<A, E>) => A | undefinedSince v2.0.0
getSuccess
Section titled “getSuccess”Extracts the success value as an Option, discarding the failure.
When to use
Use when you need to extract the success value from a Result as an
Option and discard failure information.
Details
Success<A>becomesSome<A>Failure<E>becomesNone
Example (Extracting the success as an Option)
import { Option, Result } from "effect"
console.log(Result.getSuccess(Result.succeed("ok")))// Output: { _tag: "Some", value: "ok" }
console.log(Result.getSuccess(Result.fail("err")))// Output: { _tag: "None" }See
getFailureto extract the error insteadfromOptionfor the reverse conversion
Signature
declare const getSuccess: <A, E>(self: Result<A, E>) => Option<A>Since v4.0.0
Unwraps a Result into A | E by returning the inner value regardless
of whether it is a success or failure.
Details
Success<A>returnsAFailure<E>returnsE- Useful when both channels share a compatible type
Example (Extracting the inner value)
import { Result } from "effect"
console.log(Result.merge(Result.succeed(42)))// Output: 42
console.log(Result.merge(Result.fail("error")))// Output: "error"See
matchto map each branch to a common typegetOrElseto provide a fallback for failures
Signature
declare const merge: <A, E>(self: Result<A, E>) => E | ASince v2.0.0
guards
Section titled “guards”isFailure
Section titled “isFailure”Checks whether a Result is a Failure.
When to use
Use to narrow a known Result to the Failure variant.
Details
- Acts as a TypeScript type guard, narrowing to
Failure<A, E> - After narrowing, you can access
.failureto read the error value
Example (Narrowing to failure)
import { Result } from "effect"
const result = Result.fail("oops")
if (Result.isFailure(result)) { console.log(result.failure) // Output: "oops"}See
isSuccessfor the opposite checkisResultto check if a value is any Result
Signature
declare const isFailure: <A, E>(self: Result<A, E>) => self is Failure<A, E>Since v4.0.0
isResult
Section titled “isResult”Checks whether a value is a Result (either Success or Failure).
When to use
Use to validate unknown input before operating on it as a Result.
Details
- Returns
truefor bothSuccessandFailurevariants - Acts as a TypeScript type guard, narrowing to
Result<unknown, unknown>
Example (Checking if a value is a Result)
import { Result } from "effect"
console.log(Result.isResult(Result.succeed(1)))// Output: true
console.log(Result.isResult({ value: 1 }))// Output: falseSee
isSuccess/isFailureto narrow to a specific variant
Signature
declare const isResult: (input: unknown) => input is Result<unknown, unknown>Since v4.0.0
isSuccess
Section titled “isSuccess”Checks whether a Result is a Success.
When to use
Use to narrow a known Result to the Success variant.
Details
- Acts as a TypeScript type guard, narrowing to
Success<A, E> - After narrowing, you can access
.successto read the value
Example (Narrowing to success)
import { Result } from "effect"
const result = Result.succeed(42)
if (Result.isSuccess(result)) { console.log(result.success) // Output: 42}See
isFailurefor the opposite checkisResultto check if a value is any Result
Signature
declare const isSuccess: <A, E>(self: Result<A, E>) => self is Success<A, E>Since v4.0.0
instances
Section titled “instances”makeEquivalence
Section titled “makeEquivalence”Creates an Equivalence for comparing two Result values.
Details
- Two
Successvalues are equal when thesuccessequivalence says so - Two
Failurevalues are equal when thefailureequivalence says so - A
Successand aFailureare never equal
Example (Comparing Results for equality)
import { Equivalence, Result } from "effect"
const eq = Result.makeEquivalence(Equivalence.strictEqual<number>(), Equivalence.strictEqual<string>())
console.log(eq(Result.succeed(1), Result.succeed(1)))// Output: true
console.log(eq(Result.succeed(1), Result.fail("x")))// Output: falseSignature
declare const makeEquivalence: <A, E>( success: Equivalence.Equivalence<A>, failure: Equivalence.Equivalence<E>) => Equivalence.Equivalence<Result<A, E>>Since v4.0.0
mapping
Section titled “mapping”Transforms the success channel of a Result, leaving the failure channel unchanged.
When to use
Use to apply a transformation to the success value of a Result while
preserving any existing failure.
Details
- If the result is a
Success, appliesfto the value and returns a newSuccess - If the result is a
Failure, returns it as-is - Use
flatMapiffreturns aResult(to avoid nested Results)
Example (Doubling the success value)
import { pipe, Result } from "effect"
const result = pipe( Result.succeed(3), Result.map((n) => n * 2))console.log(result)// Output: { _tag: "Success", success: 6, ... }See
mapErrorto transform only the error valuemapBothto transform both channelsflatMapwhenfreturns aResult
Signature
declare const map: { <A, A2>(f: (ok: A) => A2): <E>(self: Result<A, E>) => Result<A2, E> <A, E, A2>(self: Result<A, E>, f: (ok: A) => A2): Result<A2, E>}Since v2.0.0
mapBoth
Section titled “mapBoth”Transforms both the success and failure channels of a Result.
When to use
Use to transform both success and failure values without changing whether the result succeeds or fails.
Details
- Applies
onSuccessif the result is aSuccess - Applies
onFailureif the result is aFailure
Example (Mapping both channels)
import { pipe, Result } from "effect"
const result = pipe( Result.succeed(1), Result.mapBoth({ onSuccess: (n) => n + 1, onFailure: (e) => `Error: ${e}` }))console.log(result)// Output: { _tag: "Success", success: 2, ... }See
mapto transform only the success valuemapErrorto transform only the error valuematchto fold into a single value
Signature
declare const mapBoth: { <E, E2, A, A2>(options: { readonly onFailure: (left: E) => E2 readonly onSuccess: (right: A) => A2 }): (self: Result<A, E>) => Result<A2, E2> <E, A, E2, A2>( self: Result<A, E>, options: { readonly onFailure: (left: E) => E2; readonly onSuccess: (right: A) => A2 } ): Result<A2, E2>}Since v2.0.0
mapError
Section titled “mapError”Transforms the failure channel of a Result, leaving the success channel unchanged.
When to use
Use to transform only the failure channel while preserving success values.
Details
- If the result is a
Failure, appliesfto the error and returns a newFailure - If the result is a
Success, returns it as-is
Example (Adding context to an error)
import { pipe, Result } from "effect"
const result = pipe( Result.fail("not found"), Result.mapError((e) => `Error: ${e}`))console.log(result)// Output: { _tag: "Failure", failure: "Error: not found", ... }See
mapto transform only the success valuemapBothto transform both channels
Signature
declare const mapError: { <E, E2>(f: (err: E) => E2): <A>(self: Result<A, E>) => Result<A, E2> <A, E, E2>(self: Result<A, E>, f: (err: E) => E2): Result<A, E2>}Since v4.0.0
Runs a side-effect on the success value without altering the Result.
Details
- If the result is a
Success, callsfwith the value (return value is ignored) - If the result is a
Failure,fis not called - Returns the original
Resultunchanged (same reference) - Useful for logging, debugging, or performing mutations outside the Result chain
Example (Logging a success value)
import { pipe, Result } from "effect"
const result = pipe( Result.succeed(42), Result.tap((n) => console.log("Got:", n)))// Output: "Got: 42"
console.log(Result.isSuccess(result))// Output: trueSee
mapto transform the success value
Signature
declare const tap: { <A>(f: (a: A) => void): <E>(self: Result<A, E>) => Result<A, E> <A, E>(self: Result<A, E>, f: (a: A) => void): Result<A, E>}Since v4.0.0
models
Section titled “models”Failure (interface)
Section titled “Failure (interface)”The failure variant of Result. Wraps an error of type E.
Details
- Access the error via the
.failureproperty - Use
isFailureto narrow aResulttoFailure - Create with
fail
Example (Accessing the failure value)
import { Result } from "effect"
const failure = Result.fail("Network error")
if (Result.isFailure(failure)) { console.log(failure.failure) // Output: "Network error"}See
failto create a FailureisFailureto narrow the typeSuccessfor the other variant
Signature
export interface Failure<out A, out E> extends Pipeable, Inspectable { readonly _tag: "Failure" readonly _op: "Failure" readonly failure: E readonly [TypeId]: { readonly _A: Covariant<E> readonly _E: Covariant<A> } [Symbol.iterator](): ResultIterator<Result<A, E>> [Unify.typeSymbol]?: unknown [Unify.unifySymbol]?: ResultUnify<this> [Unify.ignoreSymbol]?: ResultUnifyIgnore}Since v4.0.0
Result (type alias)
Section titled “Result (type alias)”A value that is either Success<A, E> or Failure<A, E>.
When to use
Use when both success and failure should remain available as data and
Option would lose failure information.
Details
- Use
succeed/failto construct - Use
matchto fold both branches - Use
isSuccess/isFailureto narrow the type
E defaults to never, so Result<number> means a result that cannot fail.
Example (Creating and matching a Result)
import { Result } from "effect"
const success = Result.succeed(42)const failure = Result.fail("something went wrong")
const message = Result.match(success, { onSuccess: (value) => `Success: ${value}`, onFailure: (error) => `Error: ${error}`})console.log(message)// Output: "Success: 42"See
succeed/failto create valuesmatchto fold both branchesisSuccess/isFailurefor type guards
Signature
type Result<A, E> = Success<A, E> | Failure<A, E>Since v4.0.0
ResultUnify (interface)
Section titled “ResultUnify (interface)”Type-level utility for unifying Result types in generic contexts.
Details
This is an internal interface used by the Effect type system. You typically do not need to reference it directly.
Signature
export interface ResultUnify<T extends { [Unify.typeSymbol]?: any }> { Result?: () => T[Unify.typeSymbol] extends Result<infer A, infer E> | infer _ ? Result<A, E> : never}Since v4.0.0
ResultUnifyIgnore (interface)
Section titled “ResultUnifyIgnore (interface)”Marker interface for ignoring unification in Result types.
Details
This is an internal interface used by the Effect type system. You typically do not need to reference it directly.
Signature
export interface ResultUnifyIgnore {}Since v4.0.0
Success (interface)
Section titled “Success (interface)”The success variant of Result. Wraps a value of type A.
Details
- Access the value via the
.successproperty - Use
isSuccessto narrow aResulttoSuccess - Create with
succeed
Example (Accessing the success value)
import { Result } from "effect"
const success = Result.succeed(42)
if (Result.isSuccess(success)) { console.log(success.success) // Output: 42}See
succeedto create a SuccessisSuccessto narrow the typeFailurefor the other variant
Signature
export interface Success<out A, out E> extends Pipeable, Inspectable { readonly _tag: "Success" readonly _op: "Success" readonly success: A readonly [TypeId]: { readonly _A: Covariant<E> readonly _E: Covariant<A> } [Symbol.iterator](): ResultIterator<Result<A, E>> [Unify.typeSymbol]?: unknown [Unify.unifySymbol]?: ResultUnify<this> [Unify.ignoreSymbol]?: ResultUnifyIgnore}Since v4.0.0
pattern matching
Section titled “pattern matching”Folds a Result into a single value by applying one of two functions.
When to use
Use when a Result’s success and failure branches should be collapsed into
one plain output type.
Details
- Applies
onSuccessif the result is aSuccess - Applies
onFailureif the result is aFailure - Both branches must return the same type (or a common supertype)
Example (Folding to a string)
import { pipe, Result } from "effect"
const format = Result.match({ onSuccess: (n: number) => `Got ${n}`, onFailure: (e: string) => `Err: ${e}`})
console.log(format(Result.succeed(42)))// Output: "Got 42"
console.log(format(Result.fail("timeout")))// Output: "Err: timeout"See
mergeto extractA | Ewithout mappinggetOrElseto unwrap only the success with a fallback
Signature
declare const match: { <E, B, A, C = B>(options: { readonly onFailure: (error: E) => B readonly onSuccess: (ok: A) => C }): (self: Result<A, E>) => B | C <A, E, B, C = B>( self: Result<A, E>, options: { readonly onFailure: (error: E) => B; readonly onSuccess: (ok: A) => C } ): B | C}Since v2.0.0
sequencing
Section titled “sequencing”Collects a structure of Results into a single Result of collected values.
When to use
Use to collect independent Result values into one Result while preserving
the original structure.
Details
Accepts:
- A tuple/array: returns
Resultwith a tuple/array of success values - A struct (record): returns
Resultwith a struct of success values - An iterable: returns
Resultwith an array of success values
Short-circuits on the first Failure encountered; later elements are not inspected.
Example (Collecting a tuple and a struct)
import { Result } from "effect"
// Tupleconst tuple = Result.all([Result.succeed(1), Result.succeed("two")])console.log(tuple)// Output: { _tag: "Success", success: [1, "two"], ... }
// Structconst struct = Result.all({ x: Result.succeed(1), y: Result.fail("err") })console.log(struct)// Output: { _tag: "Failure", failure: "err", ... }See
flatMapfor chaining two Results sequentiallygenfor generator-based composition of multiple Results
Signature
declare const all: <const I extends Iterable<Result<any, any>> | Record<string, Result<any, any>>>( input: I) => [I] extends [ReadonlyArray<Result<any, any>>] ? Result< { -readonly [K in keyof I]: [I[K]] extends [Result<infer R, any>] ? R : never }, I[number] extends never ? never : [I[number]] extends [Result<any, infer L>] ? L : never > : [I] extends [Iterable<Result<infer R, infer L>>] ? Result<Array<R>, L> : Result< { -readonly [K in keyof I]: [I[K]] extends [Result<infer R, any>] ? R : never }, I[keyof I] extends never ? never : [I[keyof I]] extends [Result<any, infer L>] ? L : never >Since v2.0.0
andThen
Section titled “andThen”Provides a flexible variant of flatMap that accepts multiple input shapes.
When to use
Use to sequence a next step that may be a Result, a function, or a plain
value.
Details
The second argument can be:
- A function
(a: A) => Result<A2, E2>(same asflatMap) - A function
(a: A) => A2(auto-wrapped insucceed) - A
Result<A2, E2>value (ignores the success ofself) - A plain value
A2(auto-wrapped insucceed, ignoresself)
If self is a Failure, the second argument is never evaluated.
Example (Chaining Result values with different argument types)
import { pipe, Result } from "effect"
// With a function returning a Resultconst a = pipe( Result.succeed(1), Result.andThen((n) => Result.succeed(n + 1)))
// With a plain mapping functionconst b = pipe( Result.succeed(1), Result.andThen((n) => n + 1))
// With a constant valueconst c = pipe(Result.succeed(1), Result.andThen("done"))
console.log(a, b, c)See
flatMapfor the stricter variant (function returning Result only)mapwhen you always return a plain value
Signature
declare const andThen: { <A, A2, E2>(f: (a: A) => Result<A2, E2>): <E>(self: Result<A, E>) => Result<A2, E | E2> <A2, E2>(f: Result<A2, E2>): <A, E>(self: Result<A, E>) => Result<A2, E | E2> <A, A2>(f: (a: A) => A2): <E>(self: Result<A, E>) => Result<A2, E> <A2>(right: NotFunction<A2>): <A, E>(self: Result<A, E>) => Result<A2, E> <A, E, A2, E2>(self: Result<A, E>, f: (a: A) => Result<A2, E2>): Result<A2, E | E2> <A, E, A2, E2>(self: Result<A, E>, f: Result<A2, E2>): Result<A2, E | E2> <A, E, A2>(self: Result<A, E>, f: (a: A) => A2): Result<A2, E> <A, E, A2>(self: Result<A, E>, f: NotFunction<A2>): Result<A2, E>}Since v2.0.0
flatMap
Section titled “flatMap”Chains a function that returns a Result onto a successful value.
When to use
Use to sequence Result-returning computations that should short-circuit on
failure.
Details
- If
selfis aSuccess, appliesfto the value and returns the resultingResult - If
selfis aFailure, short-circuits and returns it unchanged - The error types are merged into a union (
E | E2) - This is the monadic
bind/>>=forResult
Example (Validating sequentially)
import { pipe, Result } from "effect"
const result = pipe( Result.succeed(5), Result.flatMap((n) => (n > 0 ? Result.succeed(n * 2) : Result.fail("not positive"))))console.log(result)// Output: { _tag: "Success", success: 10, ... }See
andThenfor a more flexible variant that also accepts plain valuesmapwhenfdoes not return aResult
Signature
declare const flatMap: { <A, A2, E2>(f: (a: A) => Result<A2, E2>): <E>(self: Result<A, E>) => Result<A2, E | E2> <A, E, A2, E2>(self: Result<A, E>, f: (a: A) => Result<A2, E2>): Result<A2, E | E2>}Since v2.0.0
transforming
Section titled “transforming”Swaps the success and failure channels of a Result.
When to use
Use to swap channels when failure-focused operations are easier through success-oriented combinators.
Details
Success<A>becomesFailure<A>(i.e.,Result<E, A>)Failure<E>becomesSuccess<E>(i.e.,Result<E, A>)- Useful when you want to apply success-oriented operations (like
map) to the error channel, then flip back
Example (Swapping channels)
import { Result } from "effect"
console.log(Result.flip(Result.succeed(42)))// Output: { _tag: "Failure", failure: 42, ... }
console.log(Result.flip(Result.fail("error")))// Output: { _tag: "Success", success: "error", ... }See
mapErrorto transform the error without swapping
Signature
declare const flip: <A, E>(self: Result<A, E>) => Result<E, A>Since v2.0.0
type lambdas
Section titled “type lambdas”ResultTypeLambda (interface)
Section titled “ResultTypeLambda (interface)”Higher-kinded type representation for Result.
Details
Used internally to integrate Result with generic type-class utilities
(e.g., map, flatMap abstractions). You typically do not need to
reference this directly.
Signature
export interface ResultTypeLambda extends TypeLambda { readonly type: Result<this["Target"], this["Out1"]>}Since v4.0.0
Result (namespace)
Section titled “Result (namespace)”Namespace containing type-level utilities for extracting the inner types
of a Result.
Example (Extracting inner types)
import type { Result } from "effect"
type R = Result.Result<number, string>
// numbertype A = Result.Result.Success<R>
// stringtype E = Result.Result.Failure<R>Since v4.0.0
Failure (type alias)
Section titled “Failure (type alias)”Extracts the failure type E from Result<A, E>.
Signature
type Failure<T> = [T] extends [Result<infer _A, infer _E>] ? _E : neverSince v4.0.0
Success (type alias)
Section titled “Success (type alias)”Extracts the success type A from Result<A, E>.
Signature
type Success<T> = [T] extends [Result<infer _A, infer _E>] ? _A : neverSince v4.0.0