UNPKG

@rustable/enum

Version:

Rust-inspired pattern matching and type-safe error handling for TypeScript. Includes Option<T> for null-safety and Result<T, E> for error handling, with comprehensive pattern matching support

271 lines (270 loc) 8.09 kB
/** * Implementation of Rust's Result type for TypeScript * Provides a type-safe way to handle operations that can fail * * @module Result */ import { Enum } from './enum'; import { Option } from './option'; /** * Interface for pattern matching on Result types * Enables exhaustive matching on Ok and Err variants * * @template T Type of the Ok value * @template E Type of the Error value * @template U Return type of the enum operation * * @example * ```typescript * const result = Ok(5).enum({ * ok: (val) => val * 2, * err: (e) => 0 * }); // result = 10 * ``` */ interface MatchResult<T, E, U> { /** * Handler for Ok values * @param val Ok value to handle * @returns Result of handling the Ok value */ Ok: (val: T) => U; /** * Handler for Err values * @param val Err value to handle * @returns Result of handling the Err value */ Err: (val: E) => U; } /** * Result type representing either success (Ok) or failure (Err) * A type-safe way to handle operations that can fail without throwing exceptions * * Key features: * - Forces explicit error handling * - Type-safe error propagation * - Rich set of combinators for value transformation * - Pattern matching support * * @template T Type of the success value * @template E Type of the error value, must extend Error * * @example * ```typescript * function divide(a: number, b: number): Result<number, Error> { * return b === 0 * ? Err(new Error("Division by zero")) * : Ok(a / b); * } * * const result = divide(10, 2) * .map(n => n * 2) // Transform if Ok * .unwrapOr(0); // Default if Err * ``` */ export declare class Result<T, E> extends Enum { static Ok<T, E>(value: T): Result<T, E>; static Err<T, E>(error: E): Result<T, E>; /** * Checks if the Result is Ok * @returns True if Ok, false if Err * * @example * ```typescript * const result = Ok(5); * if (result.isOk()) { * console.log("Operation succeeded"); * } * ``` */ isOk(): boolean; /** * Checks if the Result is Err * @returns True if Err, false if Ok * * @example * ```typescript * const result = Err(new Error("Failed")); * if (result.isErr()) { * console.log("Operation failed"); * } * ``` */ isErr(): boolean; /** * Converts to Option<T>, Some(t) if Ok(t), None if Err * @returns Option<T> representation of the Result */ ok(): Option<T>; /** * Converts to Option<E>, Some(e) if Err(e), None if Ok * @returns Option<E> representation of the Result */ err(): Option<E>; /** * Returns the Ok value or throws if Err * @throws Error if the Result is Err * @returns T Ok value */ unwrap<U = T>(): U; /** * Returns the Ok value or the provided default * @param def Default value to return if Err * @returns T Ok value or default */ unwrapOr(def: T): T; /** * Returns the Ok value or computes it from the error * @param fn Function to compute the Ok value from the error * @returns T Ok value or computed value */ unwrapOrElse(fn: (err: E) => T): T; /** * Returns the Ok value or throws the error if Err * @throws Error if the Result is Err * @returns T Ok value */ unwrapOrThrow(): T; /** * Returns the Err value or throws if Ok * @throws Error if the Result is Ok * @returns E Err value */ unwrapErr(): E; /** * Pattern matches on the Result * @param fn Match handlers for Ok and Err values * @returns Result of matching the Result */ match<U>(fn: MatchResult<T, E, U>): U; /** * Maps the Ok value using the provided function * @param fn Function to map the Ok value * @returns Result<U, E> mapped Result */ map<U>(fn: (val: T) => U): Result<U, E>; /** * Maps the Ok value using the provided function, or returns the default value if Err * @param defaultValue Default value to return if Err * @param fn Function to map the Ok value * @returns U mapped value or default */ mapOr<U>(defaultValue: U, fn: (val: T) => U): U; /** * Maps the Err value using the provided function * @param fn Function to map the Err value * @returns Result<T, U> mapped Result */ mapErr<F>(fn: (err: E) => F): Result<T, F>; /** * Throws an error if the Result is Err * @param msg Error message to include in the error * @returns T Ok value */ expect(msg: string): T; /** * Chained Result-returning functions * @param res Result to chain * @returns Result<U, E> chained Result */ and<U>(res: Result<U, E>): Result<U, E>; /** * Chain Result-returning functions * @param op Function to chain * @returns Result<U, E> chained Result */ andThen<U>(op: (val: T) => Result<U, E>): Result<U, E>; /** * Chained Result-returning functions * @param res Result to chain * @returns Result<T, F> chained Result */ or<F>(res: Result<T, F>): Result<T, F>; /** * Returns this Result if Ok, or computes a new Result if Err * @param fn Function to compute a new Result if Err * @returns Result<T, E> or Result<U, E> computed Result */ orElse<F>(fn: (err: E) => Result<T, F>): Result<T, F>; /** * Wraps a Promise into a Result, converting successful resolution to Ok and rejection to Err * @template T Type of the success value * @template E Type of the error value, must extend Error * @param promise Promise to wrap * @returns Promise<Result<T, E>> A promise that resolves to a Result * * @example * ```typescript * // Wrap a promise that might fail * const result = await Result.fromPromise<string, Error>( * fetch('https://api.example.com/data') * .then(res => res.text()) * ); * * // Handle the result * if (result.isOk()) { * console.log('Got data:', result.unwrap()); * } else { * console.error('Failed:', result.unwrapErr().message); * } * ``` */ static fromAsync<T, E>(promise: Promise<T>): Promise<Result<T, E>>; /** * Wraps a function in a Result, converting successful execution to Ok and thrown errors to Err * @template T Type of the return value * @template E Type of the error value, must extend Error * @template Args Type of the function arguments * @param fn Function to wrap * @returns A function that returns Result<T, E> * * @example * ```typescript * const parseJSON = Result.fromFn<any, Error, [string]>(JSON.parse); * * // Success case * const result1 = parseJSON('{"key": "value"}'); * if (result1.isOk()) { * console.log('Parsed:', result1.unwrap()); * } * * // Error case * const result2 = parseJSON('invalid json'); * if (result2.isErr()) { * console.error('Parse failed:', result2.unwrapErr().message); * } * ``` */ static fromFn<T, E, Args extends any[] = any[]>(fn: (...args: Args) => T): (...args: Args) => Result<T, E>; } /** * Creates a new Ok variant of Result * @template T Type of the success value * @template E Type of the error value * @param val Value to wrap in Ok * @returns Result containing the success value * * @example * ```typescript * const result = Ok(5) * .map(n => n.toString()) * .unwrapOr("error"); * ``` */ export declare function Ok<T, E>(val: T): Result<T, E>; /** * Creates a new Err variant of Result * @template T Type of the success value * @template E Type of the error value * @param err Error to wrap in Err * @returns Result containing the error * * @example * ```typescript * const result = Err(new Error("Failed")) * .mapErr(e => new TypeError(e.message)) * .unwrapOr(0); * ``` */ export declare function Err<T, E>(err: E): Result<T, E>; export {};