UNPKG

@thames/monads

Version:

Option, Result, and Either types for JavaScript - Inspired by Rust

301 lines (300 loc) 10.1 kB
import { NoneOption, Option, SomeOption } from '../option/option'; /** * Type representing any value except 'undefined'. * This is useful when working with strict null checks, ensuring that a value can be null but not undefined. */ type NonUndefined = {} | null; /** * Enum-like object to represent the type of a Result (Ok or Err). */ export declare const ResultType: { Ok: symbol; Err: symbol; }; /** * Interface for handling match operations on a Result. * Allows executing different logic based on the Result being Ok or Err. */ interface Match<T, E, U> { ok: (val: T) => U; err: (val: E) => U; } /** * The Result interface representing a success or an error. * A Result is either Ok, holding a success value, or Err, holding an error value. */ export interface Result<T extends NonUndefined, E extends NonUndefined> { /** * Represents the type of the Result: either Ok or Err. Useful for debugging and runtime checks. */ type: symbol; /** * Checks if the Result is an Ok. * * @returns true if the Result is Ok, otherwise false. * * #### Example * * ```ts * console.log(Ok(5).isOk()); // true * console.log(Err("error").isOk()); // false * ``` */ isOk(): this is OkResult<T, E>; /** * Checks if the Result is an Err. * * @returns true if the Result is Err, otherwise false. * * #### Example * * ```ts * console.log(Ok(5).isErr()); // false * console.log(Err("error").isErr()); // true * ``` */ isErr(): this is ErrResult<T, E>; /** * Converts the Result to an Option containing the success value, or None if Err. * * @returns An Option of the success value if Ok, otherwise None. * * #### Examples * * ```ts * const result = Ok(5).ok(); // Some(5) * const error = Err("error").ok(); // None * ``` */ ok(): Option<T>; /** * Converts the Result to an Option containing the error value, or None if Ok. * * @returns An Option of the error value if Err, otherwise None. * * #### Examples * * ```ts * const result = Ok(5).err(); // None * const error = Err("error").err(); // Some("error") * ``` */ err(): Option<E>; /** * Unwraps a Result, yielding the contained success value if Ok, otherwise throws an error. * * @returns The contained success value. * @throws Error if the Result is Err. * * #### Examples * * ```ts * console.log(Ok("value").unwrap()); // "value" * console.log(Err("error").unwrap()); // throws Error * ``` */ unwrap(): T | never; /** * Unwraps a Result, yielding the contained error value if Err, otherwise throws an error. * * @returns The contained error value. * @throws Error if the Result is Ok. * * #### Examples * * ```ts * console.log(Err("error").unwrapErr()); // "error" * console.log(Ok("value").unwrapErr()); // throws Error * ``` */ unwrapErr(): E | never; /** * Returns the contained success value if Ok, otherwise returns the provided default value. * * @param def The default value to return if the Result is Err. * @returns The contained success value if Ok, otherwise `def`. * * #### Examples * * ```ts * const result = Ok("value").unwrapOr("default"); // "value" * const error = Err("error").unwrapOr("default"); // "default" * ``` */ unwrapOr(def: T): T; /** * Performs a match operation on the Result, allowing for branching logic based on its state. * * @param fn An object with functions to handle each case: Ok or Err. * @returns The result of applying the appropriate function based on the Result's state. * * #### Examples * * ```ts * const result = Ok(5).match({ * ok: (val) => `Success: ${val}`, * err: (val) => `Error: ${val}`, * }); * // result === "Success: 5" * * const error = Err("failure").match({ * ok: (val) => `Success: ${val}`, * err: (val) => `Error: ${val}`, * }); * // error === "Error: failure" * ``` */ match<U extends NonUndefined>(fn: Match<T, E, U>): U; /** * Maps a Result<Ok, Err> to Result<U, Err> by applying a function to a contained Ok value, * leaving an Err value untouched. * * @param fn A function to apply to the contained Ok value. * @returns A Result containing the transformed value if Ok, or the original Err. * * #### Examples * * ```ts * const length = Ok("hello").map(s => s.length); // Ok(5) * const error = Err("error").map(s => s.length); // Err("error") * ``` */ map<U extends NonUndefined>(fn: (val: T) => U): Result<U, E>; /** * Maps a Result<Ok, Err> to Result<Ok, F> by applying a function to a contained Err value, * leaving an Ok value untouched. * * @param fn A function to apply to the contained Err value. * @returns A Result containing the original Ok, or the transformed Err. * * #### Examples * * ```ts * const ok = Ok("hello").mapErr(err => `Error: ${err}`); // Ok("hello") * const error = Err("error").mapErr(err => `Error: ${err}`); // Err("Error: error") * ``` */ mapErr<F extends NonUndefined>(fn: (err: E) => F): Result<T, F>; /** * Transforms the Result by applying a function that returns a Result to the contained Ok value, * chaining multiple potentially failing operations. * * @param fn A function that takes the current Result's Ok value and returns a new Result. * @returns The Result returned by the function if the original Result is Ok, otherwise the original Err. * * #### Examples * * ```ts * const parse = (s: string) => { * const parsed = parseInt(s); * return isNaN(parsed) ? Err("NaN") : Ok(parsed); * }; * const result = Ok("123").andThen(parse); // Ok(123) * const noResult = Err("NaN").andThen(parse); // Err("NaN") * ``` */ andThen<U extends NonUndefined>(fn: (val: T) => Result<U, E>): Result<U, E>; /** * Applies a function to the contained Err value if present, or returns the Ok value if present. * * @param fn A function that takes the current Result's Err value and returns a new Result. * @returns The original Ok if present, or the Result of the function applied to the Err value. * * #### Examples * * ```ts * const ok = Ok("hello").orElse(err => Err(`Error: ${err}`)); // Ok("hello") * const error = Err("error").orElse(err => Ok(`Recovered from ${err}`)); // Ok("Recovered from error") * ``` */ orElse<F extends NonUndefined>(fn: (err: E) => Result<T, F>): Result<T, F>; } /** * Implementation of Result representing a successful value (Ok). */ interface OkResult<T extends NonUndefined, E extends NonUndefined> extends Result<T, E> { ok(): SomeOption<T>; err(): NoneOption<E>; unwrap: () => T; unwrapErr: () => never; map<U extends NonUndefined>(fn: (val: T) => U): OkResult<U, E>; mapErr<U extends NonUndefined>(fn: (err: E) => U): OkResult<T, U>; } /** * Implementation of Result representing an error value (Err). */ interface ErrResult<T extends NonUndefined, E extends NonUndefined> extends Result<T, E> { ok(): NoneOption<T>; err(): SomeOption<E>; unwrap: () => never; unwrapErr: () => E; map<U extends NonUndefined>(fn: (val: T) => U): ErrResult<U, E>; mapErr<U extends NonUndefined>(fn: (err: E) => U): ErrResult<T, U>; } /** * Creates an Ok instance of Result containing the success value. * This function is used to represent a successful result in operations that could potentially fail. * * @param val The value to be contained within the Ok Result. * @returns A Result instance representing success and containing the provided value. * * #### Example * * ```ts * const successResult = Ok(42); * console.log(successResult.unwrap()); // Outputs: 42 * ``` */ export declare function Ok<T extends NonUndefined, E extends NonUndefined = never>(val: T): OkResult<T, E>; /** * Creates an Err instance of Result containing the error value. * This function is used to represent a failure in operations that could potentially fail. * * @param val The error value to be contained within the Err Result. * @returns A Result instance representing an error and containing the provided error value. * * #### Example * * ```ts * const errorResult = Err('Something went wrong'); * console.log(errorResult.unwrapErr()); // Outputs: Something went wrong * ``` */ export declare function Err<T extends NonUndefined, E extends NonUndefined>(val: E): ErrResult<T, E>; /** * Type guard to check if a Result is an Ok value. * This function is used to narrow down the type of a Result to OkResult in TypeScript type system. * * @deprecated Use `Result.isOk` instead. * @param val The Result to be checked. * @returns true if the provided Result is an OkResult, false otherwise. * * #### Example * * ```ts * const result = Ok('Success'); * if (isOk(result)) { * console.log('Operation was successful:', result.unwrap()); * } * ``` */ export declare function isOk<T extends NonUndefined, E extends NonUndefined>(val: Result<T, E>): val is OkResult<T, never>; /** * Type guard to check if a Result is an Err value. * This function is used to narrow down the type of a Result to ErrResult in TypeScript type system. * * @deprecated Use `Result.isErr` instead. * @param val The Result to be checked. * @returns true if the provided Result is an ErrResult, false otherwise. * * #### Example * * ```ts * const result = Err('Failure'); * if (isErr(result)) { * console.log('Operation failed with error:', result.unwrapErr()); * } * ``` */ export declare function isErr<T extends NonUndefined, E extends NonUndefined>(val: Result<T, E>): val is ErrResult<never, E>; export {};