Skip to content

AsyncResult

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 Added in v4.0.0 Source

Accessors

cause

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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.

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

Added in v4.0.0 Source

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<A, 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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

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

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

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

Signature

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

toExit

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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>;

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>;

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

Added in v4.0.0 Source

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>;

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

Added in v4.0.0 Source

Creates an Initial result, optionally marking it as waiting.

Signature

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

success

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Signature

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

waitingFrom

Added in v4.0.0 Source

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

Returns true when a value is an AsyncResult.

Signature

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

isFailure

Added in v4.0.0 Source

Returns true when an AsyncResult is a Failure.

Signature

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

isInitial

Added in v4.0.0 Source

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>;

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>;

isNotInitial

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Predicates

isWaiting

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

Added in v4.0.0 Source

Runtime identifier attached to AsyncResult values and used by isAsyncResult.

Signature

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

TypeId type

Added in v4.0.0 Source

Type-level identifier used to recognize AsyncResult values.

Signature

type TypeId = "~effect/reactivity/AsyncResult";

Utility Types

Defect interface

Added in v4.0.0 Source

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

Signature

interface Defect {
  readonly _: typeof _;
}

Interrupt interface

Added in v4.0.0 Source

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

Signature

interface Interrupt {
  readonly _: typeof _;
}

With type

Added in v4.0.0 Source

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;