UNPKG

@thames/monads

Version:

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

265 lines (264 loc) 9.27 kB
/** * 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 an Option (Some or None). */ export declare const OptionType: { Some: symbol; None: symbol; }; /** * Interface for handling match operations on an Option. * Allows executing different logic based on the Option being Some or None. */ interface Match<A, B> { some: (val: A) => B; none: (() => B) | B; } /** * The Option interface representing an optional value. * An Option is either Some, holding a value, or None, indicating the absence of a value. */ export interface Option<T extends NonUndefined> { /** * Represents the type of the Option: either Some or None. Useful for debugging and runtime checks. */ type: symbol; /** * Determines if the Option is a Some. * * @returns true if the Option is Some, otherwise false. * * #### Example * * ```ts * console.log(Some(5).isSome()); // true * console.log(None.isSome()); // false * ``` */ isSome(): this is SomeOption<T>; /** * Determines if the Option is None. * * @returns true if the Option is None, otherwise false. * * #### Example * * ```ts * console.log(Some(5).isNone()); // false * console.log(None.isNone()); // true * ``` */ isNone(): this is NoneOption<T>; /** * Performs a match operation on the Option, allowing for branching logic based on its state. * This method takes an object with functions for each case (Some or None) and executes * the corresponding function based on the Option's state, returning the result. * * @param fn An object containing two properties: `some` and `none`, which are functions * to handle the Some and None cases, respectively. * @returns The result of applying the corresponding function based on the Option's state. * * #### Example * * ```ts * const optionSome = Some(5); * const matchResultSome = optionSome.match({ * some: (value) => `The value is ${value}.`, * none: () => 'There is no value.', * }); * console.log(matchResultSome); // Outputs: "The value is 5." * * const optionNone = None; * const matchResultNone = optionNone.match({ * some: (value) => `The value is ${value}.`, * none: () => 'There is no value.', * }); * console.log(matchResultNone); // Outputs: "There is no value." * ``` */ match<U extends NonUndefined>(fn: Match<T, U>): U; /** * Applies a function to the contained value (if any), or returns a default if None. * * @param fn A function that takes a value of type T and returns a value of type U. * @returns An Option containing the function's return value if the original Option is Some, otherwise None. * * #### Examples * * ```ts * const length = Some("hello").map(s => s.length); // Some(5) * const noneLength = None.map(s => s.length); // None * ``` */ map<U extends NonUndefined>(fn: (val: T) => U): Option<U>; /** * Transforms the Option into another by applying a function to the contained value, * chaining multiple potentially failing operations. * * @param fn A function that takes a value of type T and returns an Option of type U. * @returns The Option returned by the function if the original Option is Some, otherwise None. * * #### Examples * * ```ts * const parse = (s: string) => { * const parsed = parseInt(s); * return isNaN(parsed) ? None : Some(parsed); * }; * const result = Some("123").andThen(parse); // Some(123) * const noResult = Some("abc").andThen(parse); // None * ``` */ andThen<U extends NonUndefined>(fn: (val: T) => Option<U>): Option<U>; /** * Returns this Option if it is Some, otherwise returns the option provided as a parameter. * * @param optb The alternative Option to return if the original Option is None. * @returns The original Option if it is Some, otherwise `optb`. * * #### Examples * * ```ts * const defaultOption = Some("default"); * const someOption = Some("some").or(defaultOption); // Some("some") * const noneOption = None.or(defaultOption); // Some("default") * ``` */ or(optb: Option<T>): Option<T>; /** * Returns the option provided as a parameter if the original Option is Some, otherwise returns None. * * @param optb The Option to return if the original Option is Some. * @returns `optb` if the original Option is Some, otherwise None. * * #### Examples * * ```ts * const anotherOption = Some("another"); * const someOption = Some("some").and(anotherOption); // Some("another") * const noneOption = None.and(anotherOption); // None * ``` */ and<U extends NonUndefined>(optb: Option<U>): Option<U>; /** * Returns the contained value if Some, otherwise returns the provided default value. * * @param def The default value to return if the Option is None. * @returns The contained value if Some, otherwise `def`. * * #### Examples * * ```ts * const someValue = Some("value").unwrapOr("default"); // "value" * const noneValue = None.unwrapOr("default"); // "default" * ``` */ unwrapOr(def: T): T; /** * Unwraps an Option, yielding the contained value if Some, otherwise throws an error. * * @returns The contained value. * @throws Error if the Option is None. * * #### Examples * * ```ts * console.log(Some("value").unwrap()); // "value" * console.log(None.unwrap()); // throws Error * ``` */ unwrap(): T | never; } /** * Implementation of Option representing a value (Some). */ export interface SomeOption<T extends NonUndefined> extends Option<T> { unwrap(): T; map<U extends NonUndefined>(fn: (val: T) => U): SomeOption<U>; andThen<U extends NonUndefined>(fn: (val: T) => SomeOption<U>): SomeOption<U>; andThen<U extends NonUndefined>(fn: (val: T) => NoneOption<U>): NoneOption<U>; andThen<U extends NonUndefined>(fn: (val: T) => Option<U>): Option<U>; or<U extends NonUndefined>(_optb: Option<U>): SomeOption<T>; and<U extends NonUndefined>(optb: SomeOption<U>): SomeOption<U>; and<U extends NonUndefined>(optb: NoneOption<U>): NoneOption<U>; } /** * Implementation of Option representing the absence of a value (None). */ export interface NoneOption<T extends NonUndefined> extends Option<T> { unwrap(): never; map<U extends NonUndefined>(_fn: (val: T) => U): NoneOption<U>; andThen<U extends NonUndefined>(_fn: (val: T) => Option<U>): NoneOption<U>; or<U extends NonUndefined>(optb: SomeOption<U>): SomeOption<U>; or<U extends NonUndefined>(optb: NoneOption<U>): NoneOption<U>; or<U extends NonUndefined>(optb: Option<U>): Option<U>; and<U extends NonUndefined>(_optb: Option<U>): NoneOption<U>; } /** * Creates a Some instance of Option containing the given value. * This function is used to represent the presence of a value in an operation that may not always produce a value. * * @param val The value to be wrapped in a Some Option. * @returns An Option instance representing the presence of a value. * * #### Example * * ```ts * const option = Some(42); * console.log(option.unwrap()); // Outputs: 42 * ``` */ export declare function Some<T extends NonUndefined>(val: T): SomeOption<T>; /** * The singleton instance representing None, an Option with no value. * This constant is used to represent the absence of a value in operations that may not always produce a value. * * #### Example * * ```ts * const option = None; * console.log(option.isNone()); // Outputs: true * ``` */ export declare const None: NoneOption<any>; /** * Type guard to check if an Option is a Some value. * This function is used to narrow down the type of an Option to SomeOption in TypeScript's type system. * * @deprecated Use `Option.isSome` instead. * @param val The Option to be checked. * @returns true if the provided Option is a SomeOption, false otherwise. * * #### Example * * ```ts * const option = Some('Success'); * if (isSome(option)) { * console.log('Option has a value:', option.unwrap()); * } * ``` */ export declare function isSome<T extends NonUndefined>(val: Option<T>): val is SomeOption<T>; /** * Type guard to check if an Option is a None value. * This function is used to narrow down the type of an Option to NoneOption in TypeScript's type system. * * @deprecated Use `Option.isNone` instead. * @param val The Option to be checked. * @returns true if the provided Option is a NoneOption, false otherwise. * * #### Example * * ```ts * const option = None; * if (isNone(option)) { * console.log('Option does not have a value.'); * } * ``` */ export declare function isNone<T extends NonUndefined>(val: Option<T>): val is NoneOption<T>; export {};