Skip to main content
Module

x/eitherway/mod.ts>Task

Yet Another Option and Result Implementation - providing safe abstractions for fallible flows inspired by F# and Rust
Latest
class Task
extends Promise<Result<T, E>>
Re-export
import { Task } from "https://deno.land/x/eitherway@0.10.0/mod.ts";

Task<T, E>

Task<T, E> is a composeable extension of Promise<Result<T, E>>

It is a Promise sub-class, which never rejects, but always resolves. Either with an Ok<T> or an Err<E>

It supports almost the same API as Result and allows for the same composition patterns as Result

Furthermore, Tasks exposes a few functions to ease working with collections (indexed and plain Iterables)

Constructors

new
private
Task(executor: ExecutorFn<T, E>)

Properties

readonly
[Symbol.toStringTag]: string

This well-known symbol is called by Object.prototype.toString to obtain a string representation of a value's type

This maybe useful for debugging or certain logs

The [.toString()]this#toString method is a useful short-hand in these scenarios

See the reference

Methods

andEnsure<T2, E2>(ensureFn: (v: T) => Result<T2, E2> | PromiseLike<Result<T2, E2>>): Task<T, E | E2>

Use this to conditionally pass-through the encapsulated value <T> based upon the outcome of the supplied ensureFn.

In case of Err<E>, this method short-circuits.

In case of Ok<T>, the supplied ensureFn is called with the encapsulated value <T> and if the return value is:

  • Ok<T2>: it is discarded and the original Ok<T> is returned
  • Err<E2>: Err<E2> is returned

See Task#orEnsure for the opposite case.

This is equivalent to chaining: original.andThen(ensureFn).and(original)

LHS andEnsure RHS RHS: Ok RHS: Err
LHS: Ok Ok Err
LHS: Err Err Err
andThen<T2, E2>(thenFn: (v: T) => Result<T2, E2> | PromiseLike<Result<T2, E2>>): Task<T2, E | E2>
clone(): Task<T, E>
id(): Task<T, E>

Use this to return the Task itself. Canonical identity function.

Mostly useful for flattening or en lieu of a noop.

This is mostly provided for compatibility with with Result<T, E>.

inspect(inspectFn: (v: T) => void | PromiseLike<void>): Task<T, E>
inspectErr(inspectFn: (v: E) => void | PromiseLike<void>): Task<T, E>
iter(): AsyncIterableIterator<T>

Use this to obtain an async iterator of the encapsulated value <T>

In case of failure, this method returns the empty AsyncIteratorResult

map<T2>(mapFn: (v: T) => T2 | PromiseLike<T2>): Task<T2, E>
mapErr<E2>(mapFn: (v: E) => E2 | PromiseLike<E2>): Task<T, E2>
mapOr<T2>(mapFn: (v: T) => T2 | PromiseLike<T2>, orValue: T2 | PromiseLike<T2>): Task<T2, never>
mapOrElse<T2>(mapFn: (v: T) => T2 | PromiseLike<T2>, orFn: (e: E) => T2 | PromiseLike<T2>): Task<T2, never>
orElse<T2, E2>(elseFn: (v: E) => Result<T2, E2> | PromiseLike<Result<T2, E2>>): Task<T | T2, E2>
orEnsure<T2, E2>(ensureFn: (v: E) => Result<T2, E2> | PromiseLike<Result<T2, E2>>): Task<T | T2, E>

Use this to conditionally pass-through the encapsulated value <E> based upon the outcome of the supplied ensureFn.

In case of Ok<T>, this method short-circuits.

In case of Err<E>, the supplied ensureFn is called with the encapsulated value <E> and if the return value is:

  • Ok<T2>: it is returned
  • Err<T2>: it is discarded and the original Err<E> is returned

See Task#andEnsure for the opposite case.

This is equivalent to chaining: original.orElse(ensureFn).or(original)

LHS orEnsure RHS RHS: Ok RHS: Err
LHS: Ok Ok Ok
LHS: Err Ok Err
deprecated
rise<T2, E2>(riseFn: (v: E) => Result<T2, E2> | PromiseLike<Result<T2, E2>>): Task<T | T2, E>
tap(tapFn: (v: Result<T, E>) => void | PromiseLike<void>): Task<T, E>
toString(): string

Use this to get the full string tag Short-hand for Object.prototype.toString.call(task)

See the reference

deprecated
trip<T2, E2>(tripFn: (v: T) => Result<T2, E2> | PromiseLike<Result<T2, E2>>): Task<T, E | E2>
unwrap(): Promise<T | E>
unwrapOr<T2>(orValue: T2 | PromiseLike<T2>): Promise<T | T2>
unwrapOrElse<T2>(orFn: (e: E) => T2 | PromiseLike<T2>): Promise<T | T2>
zip<T2, E2>(rhs: Result<T2, E2> | PromiseLike<Result<T2, E2>>): Task<[T, T2], E | E2>
[Symbol.asyncIterator](): AsyncIterableIterator<T extends AsyncIterable<infer U> ? U : never>

In case of success AND that the encapsulated value <T> implements the async iterator protocol, this delegates to the underlying implementation

In all other cases, it yields the empty AsyncIteratorResult

Static Properties

readonly
[Symbol.toStringTag]: string

Static Methods

Use this to create a deferred Task<T, E> which will either succeed with a value of type <T> or fail with a value of type <E>

You have to provide the generic types explicitly, otherwise <T, E> will be inferred as <unknown, unknown>

This is mostly useful when working with push-based APIs

fail<E>(error: E): Task<never, E>

Use this to create a Task which always fails with a value <E>

from<T, E>(fn: () => Result<T, E> | PromiseLike<Result<T, E>>): Task<T, E>

Use this to create a task from a function which returns a Result<T, E> or PromiseLike<Result<T, E> value.

This function should be infallible by contract.

Use Task.fromFallible if this is not the case.

fromFallible<T, E>(fn: () => T | PromiseLike<T>, errorMapFn: (reason: unknown) => E): Task<T, E>

Use this to construct a Task<T, E> from the return value of a fallible function.

fromPromise<T, E>(promise: Promise<T>, errorMapFn: (reason: unknown) => E): Task<T, E>

Use this to create a Task<T, E> from a Promise<T>.

You have to provide an errorMapFn in case the promise rejects, so that the type can be inferred.

If you are certain(!) that the provided promise will never reject, you can provide the asInfallible helper from the core module.

liftFallible<Args extends unknown[], R, E, T = R>(
fn: (...args: Args) => R | PromiseLike<R>,
errorMapFn: (reason: unknown) => E,
ctor?: (arg: R) => Result<T, E> | PromiseLike<Result<T, E>>,
): (...args: Args) => Task<T, E>

Use this lift a function into a Task context, by composing the wrapped function with a Result constructor and an error mapping function.

If no constructor is provided, Ok is used as a default.

This higher order function is especially useful to intergrate 3rd party code into your Task pipelines.

of<T, E>(value: Result<T, E> | PromiseLike<Result<T, E>>): Task<T, E>

Use this to create a task from a Result<T, E> value

succeed<T>(value: T): Task<T, never>

Use this to create a Task which always succeeds with a value <T>