Skip to main content

index

@ts-rust/std


@ts-rust/std / Result

Result

The Result module provides utilities for handling operations that can succeed or fail in a type-safe manner. Inspired by Rust's Result type, this module offers the Result and PendingResult types to manage success (Ok) and failure (Err) cases explicitly. It includes type definitions for Result, PendingResult, and related error types, as well as utility functions for creating and checking Result instances. Use this module to write more predictable and robust TypeScript code by enforcing explicit error handling.

Enumerations

EnumerationDescription

ResultErrorKind

Enumerates error codes specific to Result operations.

These codes categorize failures in ResultError instances thrown by methods such as unwrap or expect when the result’s state (e.g., Ok or Err) doesn’t match the operation’s expectations.

Classes

ClassDescription

ResultError

An error class for Result operations, extending AnyError with specific ResultErrorKind codes.

This class represents failures tied to Result methods, such as accessing a value from an Err or an error from an Ok. It provides a structured way to handle such failures by embedding a ResultErrorKind and an optional reason for additional context.

Example

const res = err<number, string>("failure");
try {
res.unwrap();
} catch (e) {
if (isResultError(e)) {
console.log(e.kind); // "UnwrapCalledOnErr"
console.log(e.message); // "[UnwrapCalledOnErr] `unwrap`: called on `Err`."
}
}

Interfaces

InterfaceDescription

EitherError

Base interface for CheckedError instances, providing methods to inspect and handle the contained error.

PendingResult

Interface defining an asynchronous Result that wraps a Promise resolving to a Result.

Extends Result functionality for pending states, with methods mirroring their synchronous counterparts but returning PendingResult or Promise for async operations. Rejections typically resolve to Err unless otherwise specified.

Resultant

Interface representing the resultant state of an operation, either a success (Ok\<T\>) or an error (Err\<E\>).

Inspired by Rust’s Result, it provides a type-safe alternative to exceptions for handling success or failure outcomes.

Type Aliases

Type AliasDescription

CheckedError

A type representing the error state of a Result, containing either an expected error of type E or an unexpected ResultError.

This type ensures exactly one error is present: either an expected error (an anticipated failure of type E) or an unexpected error (a runtime or exceptional failure). Use isExpected or isUnexpected to narrow the type if needed.

Err

Represents a failed outcome of a Result, holding a CheckedError of type E.

This type ensures errors are checked, distinguishing between expected errors of type E and unexpected runtime failures wrapped in ResultError.

ExpectedError

Represents an expected error of type E within a CheckedError.

Ok

Represents a successful outcome of a Result, holding a value of type T.

Result

A type representing the outcome of an operation, either a success (Ok) or a checked failure (Err).

Inspired by Rust’s Result, this type provides a type-safe way to handle computations that may succeed with a value of type T or fail with a checked error of type E, distinguishing expected and unexpected failures via CheckedError.

SettledResult

A Result type where both the value (T) and error (E) types have been resolved from potential PromiseLike types to their awaited forms.

UnexpectedError

Represents an unexpected error of type ResultError within a CheckedError.

Functions

FunctionDescription

err

Creates an Err variant of a Result with a void error.

Wraps undefined in a CheckedError within an Err, indicating a failed outcome with no error value for a checked Result.

Example

const x = err<number>();

expect(x.isErr()).toBe(true);
expect(x.unwrapErr().expected).toBeUndefined();
expect(x.unwrapErr().unexpected).toBeUndefined();

isCheckedError

Checks if a value is a CheckedError, narrowing its type if true.

isPendingResult

Checks if a value is a PendingResult, narrowing its type to PendingResult<unknown, unknown>.

This type guard verifies whether the input is a PendingResult, indicating it wraps a Promise resolving to a Result (either Ok or Err).

Example

const x: unknown = pendingResult(ok<number, string>(42));
const y: unknown = pendingResult(err<number, string>("failure"));
const z: unknown = ok(42); // Not a PendingResult

expect(isPendingResult(x)).toBe(true);
expect(isPendingResult(y)).toBe(true);
expect(isPendingResult(z)).toBe(false);

if (isPendingResult(x)) {
// Type narrowed to PendingResult<unknown, unknown>
expect(await x).toStrictEqual(ok(42));
}

isResult

Checks if a value is a Result, narrowing its type to Result<unknown, unknown>.

This type guard verifies whether the input conforms to the Result interface, indicating it is either an Ok or Err.

Example

const x: unknown = ok<number, string>(42);
const y: unknown = err<number, string>("failure");
const z: unknown = "not a result";

expect(isResult(x)).toBe(true);
expect(isResult(y)).toBe(true);
expect(isResult(z)).toBe(false);

if (isResult(x)) {
expect(x.isOk()).toBe(true); // Type narrowed to Result<unknown, unknown>
}

isResultError

Checks if a value is a ResultError, narrowing its type if true.

ok

Creates an Ok variant of a Result with a void value.

Wraps undefined in an Ok, indicating a successful outcome with no value (void) for a checked Result.

Example

const x = ok<string>();

expect(x.isOk()).toBe(true);
expect(x.unwrap()).toBeUndefined();

pendingErr

Creates a PendingResult\<T, E\> that resolves to Err containing the awaited error.

Takes an error or promise and wraps its resolved result in an Err, ensuring the error type is Awaited to handle any PromiseLike input.

Example

const x = pendingErr<number, string>("failure");
const y = pendingErr<string, number>(Promise.resolve(42));

expect(await x).toStrictEqual(err("failure"));
expect(await y).toStrictEqual(err(42));

pendingOk

Creates a PendingResult\<T, E\> that resolves to Ok containing the awaited value.

Takes a value or promise and wraps its resolved result in an Ok, ensuring the value type is Awaited to handle any PromiseLike input.

Example

const x = pendingOk<number, string>(42);
const y = pendingOk<string, number>(Promise.resolve("hello"));

expect(await x).toStrictEqual(ok(42));
expect(await y).toStrictEqual(ok("hello"));

pendingResult

Creates a PendingResult\<T, E\> from a result, promise, or factory function.

Accepts a Result, a Promise resolving to a Result, or a function returning either, and converts it into a pending result, handling asynchronous resolution as needed.

Example

const x = pendingResult(ok<number, string>(42));
const y = pendingResult(() => Promise.resolve(err<string, number>(42)));
const z = pendingResult(async () => err<string, boolean>(true));

expect(await x).toStrictEqual(ok(42));
expect(await y).toStrictEqual(err(42));
expect(await z).toStrictEqual(err(true));

run

Executes a synchronous action and wraps the outcome in a Result, handling errors with a custom error mapper.

The run function attempts to execute the provided action function, which returns a value of type T. If the action succeeds, it returns an Ok variant containing the result. If the action fails (throws an error), the error is passed to the mkErr function to create an error of type E, which is then wrapped in an Err variant.

This function is useful for safely executing operations that might fail, ensuring errors are handled in a type-safe way using the Result type.

Example

import { run, Result } from "@ts-rust/std";

const result: Result<{ key: string }, Error> = run(
(): { key: string } => JSON.parse('{ key: "value" }'),
(e) => new Error(`Operation failed: ${JSON.stringify(e)}`),
);
if (result.isOk()) {
console.log(result.unwrap()); // { key: "value" }
}

runAsync

Executes an asynchronous action and wraps the outcome in a PendingResult, handling errors with a custom error mapper.

The runAsync function attempts to execute the provided action function, which returns a value of type Promise<T>. If the action succeeds, it returns a PendingResult that resolves to Ok variant containing the value. If the action fails (throws an error), the error is passed to the mkErr function to create an error of type E, which is then wrapped in an Err variant.

This function is useful for safely executing operations that might fail, ensuring errors are handled in a type-safe way using the Result type.

Example

import { run, PendingResult, Result } from "@ts-rust/std";

const pendingRes: PendingResult<string, Error> = runAsync(
(): Promise<string> =>
fetch("https://api.example.com/text").then((res) => res.text()),
(e) => new Error(`Fetch failed: ${JSON.stringify(e)}`),
);

const res: Result<string, Error> = await pendingRes;

if (res.isErr()) {
console.log(res.unwrapErr().message); // Fetch failed: ...
}

runPendingResult

Safely executes an action that returns a PendingResult, capturing thrown synchronous errors as an Err variant.

The runPendingResult function executes the provided resultAction function, which returns a PendingResult<T, E>. If the action succeeds, it returns the PendingResult as-is. If the action throws an error synchronously, the error is captured and wrapped in a resolved Err variant returning UnexpectedError with a ResultErrorKind.Unexpected kind.

This overload is useful for safely running asynchronous PendingResult-producing actions, if you are not 100% sure that the action will not throw an error, ensuring that any synchronous errors are converted into an Err variant in a type-safe way.

Example

import { runPendingResult, pendingOk, pendingErr } from "@ts-rust/std";

// Successful Result
const success = await runPendingResult(() => pendingOk(42));
console.log(success.unwrap()); // 42

// Failed Result
const failure = await runPendingResult(() =>
pendingErr(new Error("Already failed")),
);
// "Expected error occurred: Error: Already failed"
console.log(failure.unwrapErr().expected?.message);

// Action throws an error
const thrown = await runPendingResult(() => {
throw new Error("Oops");
});
// "Unexpected error occurred: ResultError: [Unexpected] `runPendingResult`: result action threw an exception. Reason: Error: Oops"
console.log(thrown.unwrapErr().unexpected?.message);

runResult

Safely executes an action that returns a Result, capturing thrown synchronous errors as an Err variant.

The runResult function executes the provided resultAction function, which returns a Result<T, E>. If the action succeeds, it returns the Result as-is (either Ok<T> or Err<E>). If the action throws an error, it is captured and wrapped in an Err variant returning UnexpectedError with a ResultErrorKind.Unexpected kind.

This function is useful for safely running synchronous Result-producing actions, if you are not 100% sure that the action will not throw an error, ensuring that any thrown errors are converted into an Err variant in a type-safe way.

Example

import { runResult, ok, err } from "@ts-rust/std";

// Successful Result
const success = runResult(() => ok(42));
console.log(success.unwrap()); // 42

// Failed Result
const failure = runResult(() => err(new Error("Already failed")));
// "Expected error occurred: Error: Already failed"
console.log(failure.unwrapErr().expected?.message);

// Action throws an error
const thrown = runResult(() => {
throw new Error("Oops");
});
// "Unexpected error occurred: ResultError: [Unexpected] `runResult`: result action threw an exception. Reason: Error: Oops"
console.log(thrown.unwrapErr().unexpected?.message);