UNPKG

ts-data-forge

Version:

[![npm version](https://img.shields.io/npm/v/ts-data-forge.svg)](https://www.npmjs.com/package/ts-data-forge) [![npm downloads](https://img.shields.io/npm/dm/ts-data-forge.svg)](https://www.npmjs.com/package/ts-data-forge) [![License](https://img.shields.

360 lines 16 kB
/** @internal String literal tag to identify the 'Some' variant of Optional. */ declare const SomeTypeTagName = "ts-data-forge::Optional.some"; /** @internal String literal tag to identify the 'None' variant of Optional. */ declare const NoneTypeTagName = "ts-data-forge::Optional.none"; /** * @internal * Represents the 'Some' variant of an Optional, containing a value. * @template S The type of the contained value. */ type Some_<S> = Readonly<{ /** * @internal * Discriminant property for the 'Some' type. */ $$tag: typeof SomeTypeTagName; /** The contained value. */ value: S; }>; /** * @internal * Represents the 'None' variant of an Optional, indicating the absence of a value. */ type None_ = Readonly<{ /** * @internal * Discriminant property for the 'None' type. */ $$tag: typeof NoneTypeTagName; }>; /** * Represents an optional value that can either be 'Some' (containing a value) or 'None' (empty). * @template S The type of the value that might be present. */ export type Optional<S> = None_ | Some_<S>; /** * Namespace for the {@link Optional} type and related functions. * Provides utilities to handle values that might be absent, similar to Option types in other languages. */ export declare namespace Optional { /** * Checks if the given value is an {@link Optional}. * @param maybeOptional The value to check. * @returns `true` if the value is an {@link Optional}, otherwise `false`. */ const isOptional: (maybeOptional: unknown) => maybeOptional is Optional<unknown>; /** * Represents an {@link Optional} that contains a value. * @template S The type of the contained value. */ type Some<S> = Some_<S>; /** * Represents an {@link Optional} that does not contain a value (is empty). */ type None = None_; /** * Base type for any {@link Optional}, used for generic constraints. * Represents an {@link Optional} with an unknown value type. */ type Base = Optional<unknown>; /** * Extracts the value type `S` from an {@link Optional.Some}<S>. * If the {@link Optional} is {@link Optional.None}, resolves to `never`. * @template O The {@link Optional.Base} type to unwrap. */ type Unwrap<O extends Base> = O extends Some<infer S> ? S : never; /** * Narrows an {@link Optional.Base} type to {@link Optional.Some}<S> if it is a {@link Optional.Some}. * If the {@link Optional} is {@link Optional.None}, resolves to `never`. * @template O The {@link Optional.Base} type to narrow. */ type NarrowToSome<O extends Base> = O extends None ? never : O; /** * Narrows an {@link Optional.Base} type to {@link Optional.None} if it is a {@link Optional.None}. * If the {@link Optional} is {@link Optional.Some}<S>, resolves to `never`. * @template O The {@link Optional.Base} type to narrow. */ type NarrowToNone<O extends Base> = O extends None ? O : never; /** * Creates an {@link Optional.Some} containing the given value. * @template S The type of the value. * @param value The value to wrap in an {@link Optional.Some}. * @returns An {@link Optional.Some}<S> containing the value. * @example * ```typescript * const someValue = Optional.some(42); * console.log(Optional.isSome(someValue)); // true * console.log(Optional.unwrap(someValue)); // 42 * ``` */ const some: <S>(value: S) => Some<S>; /** * The singleton instance representing {@link Optional.None} (an empty Optional). * @example * ```typescript * const emptyValue = Optional.none; * console.log(Optional.isNone(emptyValue)); // true * console.log(Optional.unwrapOr(emptyValue, "default")); // "default" * ``` */ const none: None; /** * Checks if an {@link Optional} is {@link Optional.Some}. * Acts as a type guard. * @template O The {@link Optional.Base} type to check. * @param optional The {@link Optional} to check. * @returns `true` if the {@link Optional} is {@link Optional.Some}, `false` otherwise. */ const isSome: <O extends Base>(optional: O) => optional is NarrowToSome<O>; /** * Checks if an {@link Optional} is {@link Optional.None}. * Acts as a type guard. * @template O The {@link Optional.Base} type to check. * @param optional The {@link Optional} to check. * @returns `true` if the {@link Optional} is {@link Optional.None}, `false` otherwise. */ const isNone: <O extends Base>(optional: O) => optional is NarrowToNone<O>; /** * Unwraps an `Optional`, returning the contained value. * Throws an error if the `Optional` is `Optional.None`. * * This is a safer alternative to direct value access when you know the Optional * should contain a value. Use this method when an empty Optional represents * a programming error or unexpected condition. * * @template O The `Optional.Base` type to unwrap. * @param optional The `Optional` to unwrap. * @returns The contained value if `Optional.Some`. * @throws {Error} Error with message "`unwrapThrow()` has failed because it is `None`" if the `Optional` is `Optional.None`. * @example * ```typescript * const userInput = Optional.some(42); * console.log(Optional.unwrapThrow(userInput)); // 42 * * const empty = Optional.none; * try { * Optional.unwrapThrow(empty); // throws Error * } catch (error) { * console.log(error.message); // "`unwrapThrow()` has failed because it is `None`" * } * ``` */ const unwrapThrow: <O extends Base>(optional: O) => Unwrap<O>; /** * Unwraps an `Optional`, returning the contained value or `undefined` if empty. * * This function provides a safe way to extract values from Optionals without * throwing exceptions. It has overloaded behavior based on the type: * - For `Optional.Some<T>`: Always returns `T` (guaranteed by type system) * - For general `Optional<T>`: Returns `T | undefined` * * @template O The `Optional.Base` type to unwrap. * @param optional The `Optional` to unwrap. * @returns The contained value if `Optional.Some`, otherwise `undefined`. * @example * ```typescript * const some = Optional.some(42); * const value = Optional.unwrap(some); // 42 * * const none = Optional.none; * const result = Optional.unwrap(none); // undefined * ``` */ function unwrap<O extends Some<unknown>>(optional: O): Unwrap<O>; function unwrap<O extends Base>(optional: O): Unwrap<O> | undefined; /** * Unwraps an `Optional`, returning the contained value or a default value if it's `Optional.None`. * * Supports both direct usage and curried form for functional composition. * This is often preferred over `unwrap()` when you have a sensible fallback value. * * @template O The `Optional.Base` type to unwrap. * @template D The type of the default value. * @param optional The `Optional` to unwrap. * @param defaultValue The value to return if `optional` is `Optional.None`. * @returns The contained value if `Optional.Some`, otherwise `defaultValue`. * @example * ```typescript * // Direct usage - most common pattern * const some = Optional.some(42); * const value1 = Optional.unwrapOr(some, 0); * console.log(value1); // 42 * * const none = Optional.none; * const value2 = Optional.unwrapOr(none, 0); * console.log(value2); // 0 * * // Curried usage * const unwrapWithDefault = Optional.unwrapOr("default"); * const result = unwrapWithDefault(Optional.some("hello")); * console.log(result); // "hello" * ``` */ function unwrapOr<O extends Base, D>(optional: O, defaultValue: D): D | Unwrap<O>; function unwrapOr<S, D>(defaultValue: D): (optional: Optional<S>) => D | S; /** * Returns the `Optional` if it is `Some`, otherwise returns the alternative. * * Provides a way to chain Optional operations with fallback values. This is * particularly useful for implementing default behavior or cascading lookups. * Supports both direct usage and curried form for functional composition. * * @template O The input `Optional.Base` type. * @param optional The `Optional` to check. * @param alternative The alternative `Optional` to return if the first is `None`. * @returns The first `Optional` if `Some`, otherwise the alternative. * @example * ```typescript * const primary = Optional.none; * const fallback = Optional.some("default"); * const result = Optional.orElse(primary, fallback); * console.log(Optional.unwrap(result)); // "default" * ``` */ function orElse<O extends Base, const O2 extends Base>(optional: O, alternative: O2): O | O2; function orElse<S, S2>(alternative: Optional<S2>): (optional: Optional<S>) => Optional<S> | Optional<S2>; /** * Maps an {@link Optional}<S> to {@link Optional}<S2> by applying a function to a contained value. * If the {@link Optional} is {@link Optional.None}, it returns {@link Optional.none}. * Otherwise, it applies the `mapFn` to the value in `Optional.Some` and returns a new `Optional.Some` with the result. * @template O The input `Optional.Base` type. * @template S2 The type of the value returned by the mapping function. * @param optional The `Optional` to map. * @param mapFn The function to apply to the value if it exists. * @returns A new `Optional<S2>` resulting from the mapping, or `Optional.None` if the input was `Optional.None`. * @example * ```typescript * const someNumber = Optional.some(5); * const mapped = Optional.map(someNumber, x => x * 2); * console.log(Optional.unwrap(mapped)); // 10 * * const noneValue = Optional.none; * const mappedNone = Optional.map(noneValue, x => x * 2); * console.log(Optional.isNone(mappedNone)); // true * ``` */ function map<O extends Base, S2>(optional: O, mapFn: (value: Unwrap<O>) => S2): Optional<S2>; function map<S, S2>(mapFn: (value: S) => S2): (optional: Optional<S>) => Optional<S2>; /** * Applies a function that returns an `Optional` to the value in an `Optional.Some`. * If the input is `Optional.None`, returns `Optional.None`. * This is the monadic bind operation for `Optional`. * @template O The input `Optional.Base` type. * @template S2 The value type of the `Optional` returned by the function. * @param optional The `Optional` to flat map. * @param flatMapFn The function to apply that returns an `Optional`. * @returns The result of applying the function, or `Optional.None`. * @example * ```typescript * const parseNumber = (s: string): Optional<number> => { * const n = Number(s); * return isNaN(n) ? Optional.none : Optional.some(n); * }; * * const result = Optional.flatMap(Optional.some("42"), parseNumber); * console.log(Optional.unwrap(result)); // 42 * ``` */ function flatMap<O extends Base, S2>(optional: O, flatMapFn: (value: Unwrap<O>) => Optional<S2>): Optional<S2>; function flatMap<S, S2>(flatMapFn: (value: S) => Optional<S2>): (optional: Optional<S>) => Optional<S2>; /** * Filters an `Optional` based on a predicate. * If the `Optional` is `Some` and the predicate returns true, returns the original `Optional`. * Otherwise returns `None`. * @template O The input `Optional.Base` type. * @param optional The `Optional` to filter. * @param predicate The predicate function. * @returns The filtered `Optional`. * @example * ```typescript * const someEven = Optional.some(4); * const filtered = Optional.filter(someEven, x => x % 2 === 0); * console.log(Optional.unwrap(filtered)); // 4 * ``` */ function filter<O extends Base>(optional: O, predicate: (value: Unwrap<O>) => boolean): Optional<Unwrap<O>>; function filter<S>(predicate: (value: S) => boolean): (optional: Optional<S>) => Optional<S>; /** * Unwraps an `Optional`, returning the contained value or throwing an error with the provided message. * @template O The `Optional.Base` type to unwrap. * @param optional The `Optional` to unwrap. * @param message The error message to throw if the `Optional` is `Optional.None`. * @returns The contained value if `Optional.Some`. * @throws Error with the provided message if the `Optional` is `Optional.None`. * @example * ```typescript * const some = Optional.some(42); * const value = Optional.expectToBe(some, "Value must exist"); * console.log(value); // 42 * ``` */ function expectToBe<O extends Base>(optional: O, message: string): Unwrap<O>; function expectToBe<S>(message: string): (optional: Optional<S>) => S; /** * Combines two `Optional` values into a single `Optional` containing a tuple. * If either `Optional` is `None`, returns `None`. * @template A The value type of the first `Optional`. * @template B The value type of the second `Optional`. * @param optionalA The first `Optional`. * @param optionalB The second `Optional`. * @returns An `Optional` containing a tuple of both values, or `None`. * @example * ```typescript * const a = Optional.some(1); * const b = Optional.some("hello"); * const zipped = Optional.zip(a, b); * console.log(Optional.unwrap(zipped)); // [1, "hello"] * * const withNone = Optional.zip(a, Optional.none); * console.log(Optional.isNone(withNone)); // true * ``` */ const zip: <A, const B>(optionalA: Optional<A>, optionalB: Optional<B>) => Optional<readonly [A, B]>; /** * Converts a nullable value to an `Optional`. * * This is the primary way to lift nullable values (null or undefined) into * the Optional type system. The function treats both `null` and `undefined` * as empty values, converting them to `Optional.None`. * * @template T The type of the nullable value. * @param value The nullable value to convert. * @returns `Optional.Some<NonNullable<T>>` if the value is not null or undefined, otherwise `Optional.None`. * @example * ```typescript * const value: string | null = "hello"; * const optional = Optional.fromNullable(value); * console.log(Optional.unwrap(optional)); // "hello" * * const nullValue: string | null = null; * const noneOptional = Optional.fromNullable(nullValue); * console.log(Optional.isNone(noneOptional)); // true * ``` */ const fromNullable: <T>(value: T | null | undefined) => Optional<NonNullable<T>>; /** * Converts an `Optional` to a nullable value. * * This function extracts the value from an Optional, returning `undefined` * for empty Optionals. This is useful when interfacing with APIs or systems * that expect nullable values rather than Optional types. * * Note: This returns `undefined` (not `null`) for consistency with JavaScript's * undefined semantics and TypeScript's optional properties. * * @template O The `Optional.Base` type to convert. * @param optional The `Optional` to convert. * @returns The contained value if `Some`, otherwise `undefined`. * @example * ```typescript * const some = Optional.some(42); * console.log(Optional.toNullable(some)); // 42 * * const none = Optional.none; * console.log(Optional.toNullable(none)); // undefined * ``` */ const toNullable: <O extends Base>(optional: O) => Unwrap<O> | undefined; } export {}; //# sourceMappingURL=optional.d.mts.map