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

AsyncResult unstable

Represents observable state for asynchronous values.

AsyncResult<A, E> records whether asynchronous work has no value yet, succeeded with an A, or failed with an E. Every state also carries a waiting flag, so callers can keep showing the current value while newer work is loading, refreshing, retrying, or recovering. This module includes constructors, checks, accessors, mapping and matching helpers, ways to combine several results, and schemas for encoding or decoding results.

45 exports Since v4.0.0 Source

Accessors

cause

unstable
Since v4.0.0

Returns the failure cause when the result is a Failure, otherwise None.

Signature

declare function cause<A, E>(self: AsyncResult<A, E>): Option<Cause<E>>

error

unstable
Since v4.0.0

Returns the first typed error from a failure cause, or None for successes, initial results, defects, and interrupt-only causes.

Signature

declare function error<A, E>(self: AsyncResult<A, E>): Option<E>

getOrElse

unstable
Since v4.0.0

Returns the available value from value, or evaluates the fallback when no current or previous success exists.

Signature

declare const getOrElse: {
<B>(orElse: LazyArg<B>): <A, E>(self: AsyncResult<A, E>) => B | A;
<A, E, B>(self: AsyncResult<A, E>, orElse: LazyArg<B>): A | B;
}

getOrThrow

unstable
Since v4.0.0

Returns the available value from value, or throws NoSuchElementError when no current or previous success exists.

Signature

declare function getOrThrow<A, E>(self: AsyncResult<A, E>): A

value

unstable
Since v4.0.0

Returns the current success value, or the previous success value stored in a failure, as an Option.

Signature

declare function value<A, E>(self: AsyncResult<A, E>): Option<A>

Combinators

all

unstable
Since v4.0.0

Combines an iterable or record of AsyncResult and plain values into one AsyncResult, returning the first non-success result or a success of the collected values marked waiting when any input success is waiting.

Details

If the first non-success result is a failure, its previous success is rebuilt in the combined shape from each input's current or previous value. It is omitted if any input has no value.

Signature

declare function all<Arg extends Iterable<any, any, any> | Record<string, any>>(results: Arg): AsyncResult<[Arg] extends [readonly Array<any>] ? { [K in string | number | symbol]: [Arg[K]] extends [AsyncResult<_A, _E>] ? _A : Arg[K] } : [Arg] extends [Iterable<_A, any, any>] ? _A extends AsyncResult<_AA, _E> ? _AA : _A : [Arg] extends [Record<string, any>] ? { [K in string | number | symbol]: [Arg[K]] extends [AsyncResult<_A, _E>] ? _A : Arg[K] } : never, [Arg] extends [readonly Array<any>] ? Failure<Arg[number]> : [Arg] extends [Iterable<_A, any, any>] ? Failure<_A> : [Arg] extends [Record<string, any>] ? Failure<Arg[keyof Arg]> : never>

flatMap

unstable
Since v4.0.0

Maps the success value of an AsyncResult and flattens the result.

When to use

Use to sequence computations that may return another AsyncResult while preserving initial and failure states.

Details

Initial results are left unchanged. Failures preserve their cause and remap the stored previous success when the mapping function returns a success.

Signature

declare const flatMap: {
<A, E, B, E2>(f: (a: A, prev: Success<A, E>) => AsyncResult<B, E2>): (self: AsyncResult<A, E>) => AsyncResult<B, E | E2>;
<E, A, B, E2>(self: AsyncResult<A, E>, f: (a: A, prev: Success<A, E>) => AsyncResult<B, E2>): AsyncResult<B, E | E2>;
}

map

unstable
Since v4.0.0

Maps the success value of an AsyncResult, also mapping any previous success stored in a failure while leaving initial results unchanged.

Signature

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

match

unstable
Since v4.0.0

Pattern matches an AsyncResult by calling the handler for Initial, Failure, or Success.

Signature

declare const match: {
<A, E, X, Y, Z>(options: {
readonly onFailure: (_: Failure<A, E>) => Y;
readonly onInitial: (_: Initial<A, E>) => X;
readonly onSuccess: (_: Success<A, E>) => Z;
}): (self: AsyncResult<A, E>) => X | Y | Z;
<A, E, X, Y, Z>(self: AsyncResult<A, E>, options: {
readonly onFailure: (_: Failure<A, E>) => Y;
readonly onInitial: (_: Initial<A, E>) => X;
readonly onSuccess: (_: Success<A, E>) => Z;
}): X | Y | Z;
}
Since v4.0.0

Pattern matches a result, handling successes and initials directly while splitting failures into typed errors or squashed non-error causes passed to onDefect.

Signature

declare const matchWithError: {
<A, E, W, X, Y, Z>(options: {
readonly onDefect: (defect: unknown, _: Failure<A, E>) => Y;
readonly onError: (error: E, _: Failure<A, E>) => X;
readonly onInitial: (_: Initial<A, E>) => W;
readonly onSuccess: (_: Success<A, E>) => Z;
}): (self: AsyncResult<A, E>) => W | X | Y | Z;
<A, E, W, X, Y, Z>(self: AsyncResult<A, E>, options: {
readonly onDefect: (defect: unknown, _: Failure<A, E>) => Y;
readonly onError: (error: E, _: Failure<A, E>) => X;
readonly onInitial: (_: Initial<A, E>) => W;
readonly onSuccess: (_: Success<A, E>) => Z;
}): W | X | Y | Z;
}
Since v4.0.0

Pattern matches a result by calling onWaiting for waiting or initial states, otherwise handling successes and splitting failures into typed errors or squashed non-error causes.

Signature

declare const matchWithWaiting: {
<A, E, W, X, Y, Z>(options: {
readonly onDefect: (defect: unknown, _: Failure<A, E>) => Y;
readonly onError: (error: E, _: Failure<A, E>) => X;
readonly onSuccess: (_: Success<A, E>) => Z;
readonly onWaiting: (_: AsyncResult<A, E>) => W;
}): (self: AsyncResult<A, E>) => W | X | Y | Z;
<A, E, W, X, Y, Z>(self: AsyncResult<A, E>, options: {
readonly onDefect: (defect: unknown, _: Failure<A, E>) => Y;
readonly onError: (error: E, _: Failure<A, E>) => X;
readonly onSuccess: (_: Success<A, E>) => Z;
readonly onWaiting: (_: AsyncResult<A, E>) => W;
}): W | X | Y | Z;
}
Since v4.0.0

Replaces a Failure value's stored previous success with the latest success found in another result.

Signature

declare const replacePrevious: {
<XE, A>(previous: Option<AsyncResult<A, XE>>): <R extends AsyncResult<any, any>>(self: R) => With<R, A, Failure<R>>;
<R extends AsyncResult<any, any>, XE, A>(self: R, previous: Option<AsyncResult<A, XE>>): With<R, A, Failure<R>>;
}

toExit

unstable
Since v4.0.0

Converts a result to an Exit, succeeding with a success value, failing with a failure cause, or failing with NoSuchElementError for Initial.

Signature

declare function toExit<A, E>(self: AsyncResult<A, E>): Exit<A, NoSuchElementError | E>

touch

unstable
Since v4.0.0

Refreshes the timestamp of a Success result while preserving its value and waiting flag; non-success results are returned unchanged.

Signature

declare function touch<A extends AsyncResult<any, any>>(result: A): A

Constructors

builder

unstable
Since v4.0.0

Creates a typed builder for rendering an AsyncResult by handling waiting, initial, success, error, defect, interrupt, and failure cases.

Signature

declare function builder<A extends AsyncResult<any, any>>(self: A): Builder<never, A extends Success<_A, _E> ? _A : never, A extends Failure<_A, _E> ? _E : never, A extends Initial<_A, _E> ? true : never, A extends Failure<_A, _E> ? Defect | Interrupt : never>

fail

unstable
Since v4.0.0

Creates a Failure result from a typed error, wrapping it in Cause.fail.

Signature

declare function fail<E, A = never>(error: E, options?: {
readonly previousSuccess?: Option<Success<A, E>>;
readonly waiting?: boolean;
}): Failure<A, E>

failure

unstable
Since v4.0.0

Creates a Failure result from a Cause, optionally preserving a previous success and marking the result as waiting.

Signature

declare function failure<A, E = never>(cause: Cause<E>, options?: {
readonly previousSuccess?: Option<Success<A, E>>;
readonly waiting?: boolean;
}): Failure<A, E>
Since v4.0.0

Creates a Failure result from a Cause, carrying forward the latest success stored in a previous result.

Signature

declare function failureWithPrevious<A, E>(cause: Cause<E>, options: {
readonly previous: Option<AsyncResult<A, E>>;
readonly waiting?: boolean;
}): Failure<A, E>
Since v4.0.0

Creates a Failure result from a typed error while carrying forward the latest success stored in a previous result.

Signature

declare function failWithPrevious<A, E>(error: E, options: {
readonly previous: Option<AsyncResult<A, E>>;
readonly waiting?: boolean;
}): Failure<A, E>

fromExit

unstable
Since v4.0.0

Converts an Exit into a Success when it succeeds or a Failure carrying the exit cause when it fails.

Signature

declare function fromExit<A, E>(exit: Exit<A, E>): Success<A, E> | Failure<A, E>
Since v4.0.0

Converts an Exit to a result, preserving the latest previous success when the exit is a failure.

Signature

declare function fromExitWithPrevious<A, E>(exit: Exit<A, E>, previous: Option<AsyncResult<A, E>>): Success<A, E> | Failure<A, E>

initial

unstable
Since v4.0.0

Creates an Initial result, optionally marking it as waiting.

Signature

declare function initial<A = never, E = never>(waiting: boolean): Initial<A, E>

success

unstable
Since v4.0.0

Creates a Success result with a value and optional waiting flag or timestamp override.

Signature

declare function success<A, E = never>(value: A, options?: {
readonly timestamp?: number;
readonly waiting?: boolean;
}): Success<A, E>

waiting

unstable
Since v4.0.0

Marks an AsyncResult as waiting, optionally touching the timestamp when the result is a Success.

Signature

declare const waiting: {
(options?: {
readonly touch?: boolean;
}): <R extends AsyncResult<any, any>>(self: R) => R;
<R extends AsyncResult<any, any>>(self: R, options?: {
readonly touch?: boolean;
}): R;
}

waitingFrom

unstable
Since v4.0.0

Creates a waiting result from an optional previous result, using Initial(true) when no previous result exists.

Signature

declare function waitingFrom<A, E>(previous: Option<AsyncResult<A, E>>): AsyncResult<A, E>

Guards

Since v4.0.0

Returns true when a value is an AsyncResult.

Signature

declare function isAsyncResult(u: unknown): u is AsyncResult<unknown, unknown>

isFailure

unstable
Since v4.0.0

Returns true when an AsyncResult is a Failure.

Signature

declare function isFailure<A, E>(result: AsyncResult<A, E>): result is Failure<A, E>

isInitial

unstable
Since v4.0.0

Returns true when an AsyncResult is in the Initial state.

Signature

declare function isInitial<A, E>(result: AsyncResult<A, E>): result is Initial<A, E>
Since v4.0.0

Returns true when an AsyncResult is a Failure whose cause contains only interruptions.

Signature

declare function isInterrupted<A, E>(result: AsyncResult<A, E>): result is Failure<A, E>
Since v4.0.0

Returns true when an AsyncResult is either Success or Failure.

Signature

declare function isNotInitial<A, E>(result: AsyncResult<A, E>): result is Success<A, E> | Failure<A, E>

isSuccess

unstable
Since v4.0.0

Returns true when an AsyncResult is a Success.

Signature

declare function isSuccess<A, E>(result: AsyncResult<A, E>): result is Success<A, E>

Models

AsyncResult

type unstable
Since v4.0.0

Represents the state of an asynchronous value as Initial, Success, or Failure, with a waiting flag for in-flight refreshes.

Signature

type AsyncResult<A, E = never> = Initial<A, E> | Success<A, E> | Failure<A, E>

Builder

type unstable
Since v4.0.0

Fluent renderer for AsyncResult values that tracks unhandled cases at the type level and exposes exhaustive only after all possible cases are handled.

Signature

type Builder<Out, A, E, I, F> = Pipeable & {
onWaiting<B>(f: (result: AsyncResult<A, E>) => B): Builder<Out | B, A, E, I, F>;
orElse<B>(orElse: LazyArg<B>): Out | B;
orNull(): Out | null;
render(): [A | I] extends [never] ? Out : Out | null;
} & [A | E | I | F] extends [never] ? {
exhaustive(): Out;
} : unknown & [I] extends [never] ? unknown : {
onInitial<B>(f: (result: Initial<A, E>) => B): Builder<Out | B, A, E, never, F>;
onInitialOrWaiting<B>(f: (result: AsyncResult<A, E>) => B): Builder<Out | B, A, E, never, F>;
} & [A] extends [never] ? unknown : {
onSuccess<B>(f: (value: A, result: Success<A, E>) => B): Builder<Out | B, never, E, I, F>;
} & [E] extends [never] ? unknown : {
onError<B>(f: (error: E, result: Failure<A, E>) => B): Builder<Out | B, A, never, I, F>;
onErrorIf<B, C>(refinement: Refinement<E, B>, f: (error: B, result: Failure<A, E>) => C): Builder<Out | C, A, EqualsWith<E, B, E, Exclude<E, B>>, I, F>;
onErrorIf<C>(predicate: Predicate<E>, f: (error: E, result: Failure<A, E>) => C): Builder<Out | C, A, E, I, F>;
onErrorTag<Tags extends readonly Array<Tags<E>>, B>(tags: Tags, f: (error: ExtractTag<E, Tags[number]>, result: Failure<A, E>) => B): Builder<Out | B, A, Exclude<E, {
readonly _tag: K;
}>, I, F>;
onErrorTag<Tag extends string, B>(tag: Tag, f: (error: ExtractTag<E, Tag>, result: Failure<A, E>) => B): Builder<Out | B, A, Exclude<E, {
readonly _tag: K;
}>, I, F>;
} & [E | F] extends [never] ? unknown : {
onFailure<B>(f: (cause: Cause<E>, result: Failure<A, E>) => B): Builder<Out | B, A, never, I, never>;
} & Interrupt extends F ? {
onInterrupt<B>(f: (interruptors: ReadonlySet<number>, result: Failure<A, E>) => B): Builder<Out | B, A, E, I, Exclude<F, Interrupt>>;
} : unknown & Defect extends F ? {
onDefect<B>(f: (defect: unknown, result: Failure<A, E>) => B): Builder<Out | B, A, E, I, Exclude<F, Defect>>;
} : unknown

Failure

interface unstable
Since v4.0.0

Failed AsyncResult containing a failure cause and the latest previous success when one is available.

Signature

interface Failure<A, E = never> extends Proto<A, E> {
readonly _tag: "Failure";
readonly cause: Cause<E>;
readonly previousSuccess: Option<Success<A, E>>;
}

Initial

interface unstable
Since v4.0.0

Initial AsyncResult state before a success value or failure cause is available.

Signature

interface Initial<A, E = never> extends Proto<A, E> {
readonly _tag: "Initial";
}

Success

interface unstable
Since v4.0.0

Successful AsyncResult containing the current value, its timestamp, and the shared waiting flag.

Signature

interface Success<A, E = never> extends Proto<A, E> {
readonly _tag: "Success";
readonly timestamp: number;
readonly value: A;
}

Other

AsyncResult

unstable
Since v4.0.0

Namespace containing type-level helpers and the shared prototype shape for AsyncResult values.

Predicates

isWaiting

unstable
Since v4.0.0

Returns whether an AsyncResult is currently waiting for an asynchronous computation or refresh to finish.

Signature

declare function isWaiting<A, E>(result: AsyncResult<A, E>): boolean

Schemas

Schema

unstable
Since v4.0.0

Creates a schema for AsyncResult values using optional schemas for success values and failure errors.

Signature

declare const Schema: <A extends Constraint = Never, E extends Constraint = Never>(options: {
readonly error?: E;
readonly success?: A;
}) => Schema<A, E>

Schema

interface unstable
Since v4.0.0

Schema interface for AsyncResult values, retaining the schemas used for success values and failure errors.

Signature

interface Schema<Success extends Schema_.Constraint, Error extends Schema_.Constraint> extends declareConstructor<AsyncResult<Success["Type"], Error["Type"]>, AsyncResult<Success["Encoded"], Error["Encoded"]>, readonly [Success, Schema_.Cause<Error, Schema_.Defect>]> {
constructor(_: never);
readonly error: Error;
readonly success: Success;
}

Type IDs

TypeId

unstable
Since v4.0.0

Runtime identifier attached to AsyncResult values and used by isAsyncResult.

Signature

declare const TypeId: "~effect/reactivity/AsyncResult"

TypeId

type unstable
Since v4.0.0

Type-level identifier used to recognize AsyncResult values.

Signature

type TypeId = "~effect/reactivity/AsyncResult"

Utility Types

Defect

interface unstable
Since v4.0.0

Type marker used by Builder to track whether defect failures still need to be handled.

Signature

interface Defect {
readonly _: typeof _;
}

Interrupt

interface unstable
Since v4.0.0

Type marker used by Builder to track whether interrupt failures still need to be handled.

Signature

interface Interrupt {
readonly _: typeof _;
}

With

type unstable
Since v4.0.0

Rebuilds an AsyncResult with new success and failure types while preserving the variant of another result.

Signature

type With<R extends AsyncResult<any, any>, A, E> = R extends Initial<infer _A, infer _E> ? Initial<A, E> : R extends Success<infer _A, infer _E> ? Success<A, E> : R extends Failure<infer _A, infer _E> ? Failure<A, E> : never