@ts-rust/std
Version:
Rust-inspired utilities for TypeScript: Option, Result, and error handling for safer, more predictable code.
350 lines • 14.7 kB
TypeScript
import type { CheckedError, PendingResult, Result } from "./interface";
/**
* Creates an {@link Ok} variant of a {@link Result} with a `void` value.
*
* Wraps `undefined` in an {@link Ok}, indicating a successful outcome with
* no value (`void`) for a checked {@link Result}.
*
* @template E - The type of the potential error.
* @param value - The `void` value (typically omitted or `undefined`).
* @returns A {@link Result} containing `undefined` as {@link Ok}.
*
* @example
* ```ts
* const x = ok<string>();
*
* expect(x.isOk()).toBe(true);
* expect(x.unwrap()).toBeUndefined();
* ```
*/
export declare function ok<E>(value: void): Result<void, E>;
/**
* Creates an {@link Ok} variant of a {@link Result} containing the given value.
*
* Wraps the provided value in an {@link Ok}, indicating a successful outcome
* for a checked {@link Result}.
*
* @template T - The type of the value.
* @template E - The type of the potential error.
* @param value - The value to wrap in {@link Ok}.
* @returns A {@link Result} containing the value as {@link Ok}.
*
* @example
* ```ts
* const x = ok<number, string>(42);
*
* expect(x.isOk()).toBe(true);
* expect(x.unwrap()).toBe(42);
* ```
*/
export declare function ok<T, E>(value: T): Result<T, E>;
/**
* Creates an {@link Err} variant of a {@link Result} with a `void` error.
*
* Wraps `undefined` in a {@link CheckedError} within an {@link Err},
* indicating a failed outcome with no error value for a checked {@link Result}.
*
* @template T - The type of the potential value.
* @param error - The `void` error (typically omitted or `undefined`).
* @returns A {@link Result} containing `undefined` as {@link Err}.
*
* @example
* ```ts
* const x = err<number>();
*
* expect(x.isErr()).toBe(true);
* expect(x.unwrapErr().expected).toBeUndefined();
* expect(x.unwrapErr().unexpected).toBeUndefined();
* ```
*/
export declare function err<T>(error: void): Result<T, void>;
/**
* Creates an {@link Err} variant of a {@link Result} containing the given error.
*
* Wraps the provided error in a {@link CheckedError} within an {@link Err},
* indicating a failed outcome for a checked {@link Result}. This function accepts
* raw error value or {@link CheckedError}.
*
* - If called with an error of type `E`, it creates an {@link ExpectedError} variant.
* - If called with a {@link CheckedError}, it uses the error as is.
*
* @template T - The type of the potential value.
* @template E - The type of the expected error.
* @param error - The error to wrap in {@link Err}, as a raw `E` or {@link CheckedError}.
* @returns A {@link Result} containing the error as {@link Err}.
*
* @example
* ```ts
* const oops = new ResultError("err", ResultErrorKind.Unexpected);
* const x = err<number, string>("failure");
* const y = err<number, string>(oops);
*
* expect(x.isErr()).toBe(true);
* expect(x.unwrapErr().expected).toBe("failure");
* expect(y.unwrapErr().unexpected).toBe(oops);
* ```
*/
export declare function err<T, E>(error: E | CheckedError<E>): Result<T, E>;
/**
* Executes a synchronous action and wraps the outcome in a {@link Result},
* handling errors with a custom error mapper.
*
* The {@link run} function attempts to execute the provided `action` function,
* which returns a value of type `T`. If the action succeeds, it returns an
* {@link 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 {@link Err} variant.
*
* This function is useful for safely executing operations that might fail,
* ensuring errors are handled in a type-safe way using the {@link Result} type.
*
* @param action - A function that performs the operation, returning a value of type `T`.
* @param mkErr - A function that converts an error (of type `unknown`) into an error of type `E`.
* @returns A `Result<T, E>` containing either the successful result (`Ok<T>`) or the mapped error (`Err<E>`).
*
* @example
* ```ts
* 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" }
* }
* ```
*/
export declare function run<T, E>(action: () => Awaited<T>, mkErr: (error: unknown) => Awaited<E>): Result<T, E>;
/**
* Executes an asynchronous action and wraps the outcome in a {@link PendingResult},
* handling errors with a custom error mapper.
*
* The {@link runAsync} function attempts to execute the provided `action` function,
* which returns a value of type `Promise<T>`. If the action succeeds, it returns a
* {@link PendingResult} that resolves to {@link 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 {@link Err} variant.
*
* This function is useful for safely executing operations that might fail,
* ensuring errors are handled in a type-safe way using the {@link Result} type.
*
* @param action - A function that performs the operation, returning a `Promise` resolving to `T`.
* @param mkErr - A function that converts an error (of type `unknown`) into an error of type `E`.
* @returns A `PendingResult<T, E>` that resolves to either a value (`Ok<T>`) or the mapped error (`Err<E>`).
*
* @example
* ```ts
* 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: ...
* }
* ```
*/
export declare function runAsync<T, E>(action: () => Promise<T>, mkErr: (error: unknown) => Awaited<E>): PendingResult<T, E>;
/**
* Safely executes an action that returns a {@link Result}, capturing thrown
* synchronous errors as an {@link Err} variant.
*
* The {@link runResult} function executes the provided `resultAction` function,
* which returns a `Result<T, E>`. If the action succeeds, it returns the {@link Result}
* as-is (either `Ok<T>` or `Err<E>`). If the action throws an error, it is
* captured and wrapped in an {@link Err} variant returning {@link 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 {@link Err} variant in a type-safe way.
*
* @param getResult - A function that returns a `Result<T, E>`.
* @returns A `Result<T, E>` containing either the original `Result` from `resultAction` or an `Err<E>` if the action throws an error.
*
* @example
* ```ts
* 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);
* ```
*/
export declare function runResult<T, E>(getResult: () => Result<T, E>): Result<T, E>;
/**
* Safely executes an action that returns a {@link PendingResult}, capturing
* thrown synchronous errors as an {@link Err} variant.
*
* The {@link runPendingResult} function executes the provided `resultAction`
* function, which returns a `PendingResult<T, E>`. If the action succeeds, it
* returns the {@link PendingResult} as-is. If the action throws an error synchronously,
* the error is captured and wrapped in a resolved {@link Err} variant returning
* {@link 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 {@link Err} variant in a type-safe way.
*
* @param getResult - A function that returns a `Result<T, E>`, `PendingResult<T, E>` or a `Promise<Result<T, E>>`.
* @returns A `PendingResult<T, E>` containing either the original `PendingResult` from `resultAction` or a resolved `Promise` with an `Err<E>` if the action throws synchronously.
*
* @example
* ```ts
* 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);
* ```
*/
export declare function runPendingResult<T, E>(getResult: () => Result<T, E> | PendingResult<T, E> | Promise<Result<T, E>>): PendingResult<T, E>;
/**
* Creates a {@link PendingResult | PendingResult\<T, E>} that resolves to
* {@link Ok} containing the awaited value.
*
* Takes a value or promise and wraps its resolved result in an {@link Ok},
* ensuring the value type is `Awaited` to handle any `PromiseLike` input.
*
* @template T - The type of the input value or promise.
* @template E - The type of the potential error.
* @param value - The value or promise to wrap in {@link Ok}.
* @returns A {@link PendingResult} resolving to {@link Ok} with the awaited value.
*
* @example
* ```ts
* 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"));
* ```
*/
export declare function pendingOk<T, E>(value: T | Promise<T>): PendingResult<Awaited<T>, Awaited<E>>;
/**
* Creates a {@link PendingResult | PendingResult\<T, E>} that resolves to
* {@link Err} containing the awaited error.
*
* Takes an error or promise and wraps its resolved result in an {@link Err},
* ensuring the error type is `Awaited` to handle any `PromiseLike` input.
*
* @template T - The type of the potential value.
* @template E - The type of the input error or promise.
* @param error - The error or promise to wrap in {@link Err}.
* @returns A {@link PendingResult} resolving to {@link Err} with the awaited error.
*
* @example
* ```ts
* 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));
* ```
*/
export declare function pendingErr<T, E>(error: E | CheckedError<E> | Promise<E> | Promise<CheckedError<E>>): PendingResult<Awaited<T>, Awaited<E>>;
/**
* Creates a {@link PendingResult | PendingResult\<T, E>} from a result,
* promise, or factory function.
*
* Accepts a {@link Result}, a `Promise` resolving to a {@link Result}, or
* a function returning either, and converts it into a pending result, handling
* asynchronous resolution as needed.
*
* @template T - The type of the value in the result.
* @template E - The type of the expected error in the result.
* @param resultOrFactory - The {@link Result}, promise, or factory function producing a {@link Result}.
* @returns A {@link PendingResult} resolving to the provided or produced result.
*
* @example
* ```ts
* 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));
* ```
*/
export declare function pendingResult<T, E>(resultOrFactory: Result<T, E> | Promise<Result<T, E>> | (() => Result<T, E> | Promise<Result<T, E>>)): PendingResult<T, E>;
/**
* Checks if a value is a {@link Result}, narrowing its type to
* `Result<unknown, unknown>`.
*
* This type guard verifies whether the input conforms to the {@link Result}
* interface, indicating it is either an {@link Ok} or {@link Err}.
*
* @param x - The value to check.
* @returns `true` if the value is a {@link Result}, narrowing to `Result<unknown, unknown>`.
*
* @example
* ```ts
* 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>
* }
* ```
*/
export declare function isResult(x: unknown): x is Result<unknown, unknown>;
/**
* Checks if a value is a {@link PendingResult}, narrowing its type to
* `PendingResult<unknown, unknown>`.
*
* This type guard verifies whether the input is a {@link PendingResult},
* indicating it wraps a `Promise` resolving to a {@link Result}
* (either {@link Ok} or {@link Err}).
*
* @param x - The value to check.
* @returns `true` if the value is a {@link PendingResult}, narrowing to `PendingResult<unknown, unknown>`.
*
* @example
* ```ts
* 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));
* }
* ```
*/
export declare function isPendingResult(x: unknown): x is PendingResult<unknown, unknown>;
//# sourceMappingURL=result.d.ts.map