UNPKG

@rslike/std

Version:

JavaScript Standard library without udndefined behavior!

1,164 lines (1,143 loc) 65.2 kB
/** MIT License Copyright (c) 2023 Vitali Haradkou Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** * Common error. Usually throws when something is not defined. * @see {@link https://github.com/vitalics/rslike/wiki/UndefinedBehaviorError Wiki} */ declare class UndefinedBehaviorError extends Error { } /** Node.js inspection symbol */ declare const customInspectSymbol: unique symbol; /** MIT License Copyright (c) 2023 Vitali Haradkou Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ type Fn<R = unknown, A extends readonly unknown[] = [], This = void> = Function & ((this: This, ...args: A) => R); type ComparatorFn<Self, Other = Self> = (self: Self, other: Other) => boolean; type IsNever<T> = [T] extends [never] ? true : false; type IsPromise<T> = T extends Promise<any> ? true : false; type ErrorLike = { readonly name: string; readonly message: string; readonly stack?: string; readonly cause?: unknown; }; type TError<ErrLike extends ErrorLike> = Error & ErrLike; type TUndefinedBehaviorError<ErrLike extends Omit<ErrorLike, "name">> = TError<{ readonly name: "UndefinedBehaviorError"; } & ErrLike>; type ToStack<Messages extends readonly string[] = readonly [], R extends string = ""> = Messages extends readonly [ infer Head extends string, ...infer Tail extends string[] ] ? `${Head} ${ToStack<Tail, R>}` : R; /** MIT License Copyright (c) 2023 Vitali Haradkou Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject ot the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** Option possible statuses */ declare const Status$1: Readonly<{ readonly None: "None"; readonly Some: "Some"; }>; type StatusKey$1 = keyof typeof Status$1; type SomeFn<T> = (value?: T | null | undefined) => void; type NoneFn<E = unknown> = (reason?: E) => void; type Executor$1<T, E = unknown, R = T> = (some: SomeFn<T>, none: NoneFn<E>) => void | R; /** * Type Option represents an optional value: every `Option` is either `Some` and contains a value, or `None`, and does not. Option types are very common in code, as they have a number of uses: * - Initial values * - Return values for functions that are not defined over their entire input range (partial functions) * - Return value for otherwise reporting simple errors, where `None` is returned on error * - Optional fields * - Optional function arguments * - Nullable values * - Swapping things out of difficult situations * * `Options` are commonly paired with pattern matching to query the presence of a value and take action, always accounting for the `None` case. * * @see {@link https://github.com/vitalics/rslike/wiki/Option WIKI} * @export * @class Option * @implements {Symbol.iterator} * @implements {Symbol.asyncIterator} * @implements {OptionLike<T>} * @template T */ declare class Option<const T, const S extends (typeof Status$1)[StatusKey$1] = IsNever<T> extends true ? typeof Status$1.None : T extends undefined ? typeof Status$1.None : [T] extends [null] ? typeof Status$1.None : (typeof Status$1)[StatusKey$1]> { private value; private status; constructor(executor: Executor$1<T>); /** * Returns the contained `Some` value, consuming the self value. * @example * const x = Some("value"); * x.expect("fruits are healthy") === "value"; // true * * const y: Option<string> = None(); * y.expect("fruits are healthy"); // throws with `fruits are healthy` * @param {string} reason error message * @throws `Error` if value is `null` or `undefined` * @return {*} {Value} */ expect(reason: string): NonNullable<T>; /** * Returns the contained `Some` value, consuming the self value. * * Because this function may throws, its use is generally discouraged. Instead, prefer to use pattern matching and handle the None case explicitly, or call `unwrapOr`, `unwrapOrElse`, or `unwrapOrDefault`. * * @throws `Error` when value is `None`, `null` or `undefined` * * @example * const x = Some("air"); * x.unwrap() === "air"; * * const x: Option<string> = None(); * x.unwrap() // fails * @return {*} */ unwrap(): S extends typeof Status$1.None ? never : T extends void | null | undefined ? never : NonNullable<T>; /** * Returns the contained `Some` value or a provided default. * @example * const x = Some("air"); * x.unwrapOr("another") === "air"; * * const x: Option<string> = None(); * x.unwrapOr("another") === 'another' * @param {T} fallback fallback value * @return {*} {Value} */ unwrapOr<const U>(fallback: U): S extends typeof Status$1.Some ? NonNullable<T> : U; /** * Returns the contained `Some` value or computes it from a closure. * @example * const k = 10; * Some(4).unwrapOrElse(() => 2 * k) === 4 * None().unwrapOrElse(() => 2 * k) === 20 * @param predicate function to call when `Option` is `None` * @throws `UndefinedBehaviorError` if `predicate` is not a function * @return Unwrapped value or prdicate result */ unwrapOrElse<const U>(predicate: () => U): S extends typeof Status$1.Some ? NonNullable<T> : U; /** * Maps an `Option<T>` to `Option<U>` by applying a function to a contained value (if `Some`) or returns `None` (if `None`). * * @example * const maybeSomeString = Some("Hello, World!"); * const maybeSomeLen = maybeSomeString.map(s => s.length); * maybeSomeLen === Some(13)); * * const x: Option<string> = None(); * x.map(s => s.length) === None(); * @template U * @param predicate function to evaluate when `Option` have `Some` value * @throws `UndefinedBehaviorError` if `predicate` is not a function * @return `Option` instance */ map<const U>(predicate: (value: T) => U): S extends typeof Status$1.Some ? U extends null ? Option<U, typeof Status$1.None> : U extends undefined ? Option<U, typeof Status$1.None> : Option<NonNullable<U>, typeof Status$1.Some> : Option<U, typeof Status$1.None>; /** * Returns the provided default result (if none), or applies a function to the contained value (if any). * * Arguments passed to `mapOr` are eagerly evaluated; if you are passing the result of a function call, it is recommended to use `mapOrElse`, which is lazily evaluated. * * @example * const x = Some("foo"); * x.mapOr(42, v => v.length) === 3; * * const x: Option<string> = None(); * x.mapOr(42, v => v.len() === 42; * @param {U} fallback fallback value returns when `Option` have `None` status * @param predicate function to evaluate when `Option` have `Some` status * @throws `UndefinedBehaviorError` if `predicate` is not a function * @return */ mapOr<const U>(fallback: U, predicate: (value: T) => U): S extends typeof Status$1.None ? U : T; /** * Computes a default function result (if none), or applies a different function to the contained value (if any). * * @example * const k = 21; * * const x = Some("foo"); * x.mapOrElse(() => 2 * k, v => v.length) === 3; * * const x: Option<string> = None(); * x.mapOrElse(() => 2 * k, v => v.length) === 42; * @template U * @throws `UndefinedBehaviorError` if `noneFn` is not a function * @throws `UndefinedBehaviorError` if `someFn` is not a function * @return {*} {U} */ mapOrElse<const U>(noneFn: () => U, someFn: (value: T) => U): U; /** * Transforms the `Option<T>` into a `Result<T, E>`, mapping `Some(v)` to `Ok(v)` and None to `Err(err)`. * * Arguments passed to `okOr` are eagerly evaluated; if you are passing the result of a function call, it is recommended to use `okOrElse`, which is lazily evaluated. * * @example * const x = Some("foo"); * String(x.okOr(0)) === String(Ok("foo")); * * const y: Option<string> = None(); * y.okOr(0) === Err(0); */ okOr<const Err>(err: Err): Result<T, Err>; /** * Transforms the `Option<T>` into a `Result<T, E>`, mapping `Some(v)` to `Ok(v)` and None to `Err(err())`. * * @example * const x = Some("foo"); * console.assert(x.okOrElse(() => 0) === Ok("foo")); * * let y: Option<string> = None(); * console.assert(y.okOrElse(() => 0) === Err(0)); * @return {*} {Value} */ okOrElse<const Err = unknown>(err: () => Err): Result<T, Err>; /** * Returns `None` if the option is `None`, otherwise returns `optb`. * * Arguments passed to and are eagerly evaluated; if you are passing the result of a function call, it is recommended to use `andThen`, which is lazily evaluated. * @throws `UndefinedBehaviorError` if `optb` is not an instance of `Option` * @example * const x = Some(2); * const y: Option<string> = None(); * console.assert(x.and(y) === None()); * // another example * let x: Option<number> = None(); * let y = Some("foo"); * console.assert(x.and(y) === None()); * // another example * let x = Some(2); * let y = Some("foo"); * console.assert(x.and(y) === Some("foo")); * // another example * let x: Option<number> = None(); * let y: Option<string> = None(); * console.assert(x.and(y) === None()); */ and<const U, const O extends Option<any, any> = Option<U>>(optb: O): S extends typeof Status$1.None ? Option<T, typeof Status$1.None> : O; /** * Returns `None` if the option is `None`, otherwise calls `f` with the wrapped value and returns the result. * * Some languages call this operation flatmap. * * @example * function toString(x: number): Option<string> { * return Some(String(x)); * } * console.assert(Some(2).andThen(toString) === Some(2.toString())); * console.assert(None().andThen(toString) === None()); * @template U * @throws `UndefinedBehaviorError` if `predicate` is not a function * @throws `UndefinedBehaviorError` if return type of `predicate` is not an instance of `Option` * @return {*} {Option<U>} */ andThen<const U, O extends Option<U, (typeof Status$1)[StatusKey$1]>>(predicate: (value: T) => O): S extends typeof Status$1.None ? Option<U, typeof Status$1.None> : O; /** * Returns `None` if the option is `None`, otherwise calls predicate with the wrapped value and returns: * * - `Some(t)` if predicate returns `true` (where t is the wrapped value), an * - `None` if predicate returns `false` * * @example * function isEven(n: number): boolean { * return n % 2 == 0 * } * console.assert(None().filter(isEven) === None()); * console.assert(Some(3).filter(isEven) === None()); * console.assert(Some(4).filter(isEven) === Some(4)); * @throws `UndefinedBehaviorError` if `predicate` is not a function * @throws `UndefinedBehaviorError` if return type of `predicate` function is not a `boolean` * @param predicate * @return {*} {Option<Value>} */ filter(predicate: (value: T) => boolean): S extends typeof Status$1.None ? Option<T, typeof Status$1.None> : Option<T, StatusKey$1>; /** * Returns `Some` if exactly one of self, optb is `Some`, otherwise returns `None`. * @throws `UndefinedBehaviorError` if `optb` is not an instance of `Option` * @param optb * @return {*} {Option<Value>} */ xor<const U, O extends Option<any, any> = Option<U>>(optb: O): S extends typeof Status$1.Some ? this : O extends Option<any, infer OS extends StatusKey$1> ? OS extends typeof Status$1.Some ? O : Option<any, typeof Status$1.None> : Option<any, typeof Status$1.None>; /** * Inserts value into the option, then returns a mutable reference to it. * * If the option already contains a value, the old value is dropped. * * See also `getOrInsert`, which doesn’t update the value if the option already contains `Some`. * @see {@link Option.getOrInsert} * @example * const opt = None(); * const val = opt.insert(1); * console.assert(val === 1); * console.assert(opt.unwrap() === 1); * // another example * const val = opt.insert(2); * console.assert(val === 2); * * @param value * @return {*} {Option<Value>} */ insert<const U>(value?: U | null): U extends undefined ? Option<U, typeof Status$1.None> : U extends null ? Option<U, typeof Status$1.None> : Option<NonNullable<U>, typeof Status$1.Some>; /** * Replaces the actual value in the option by the value given in parameter, returning the old value if present, leaving a `Some` in its place without deinitializing either one. * * @example * const x = Some(2); * const old = x.replace(5); * console.assert(x === Some(5)); * console.assert(old === Some(2)); * // another example * const x = None(); * const old = x.replace(3); * console.assert(x === Some(3)); * console.assert(old === None()); * @param {T} value * @return {*} {Option<Value>} */ replace<const U>(value: U): this; /** * Zips self with another Option. * * If self is `Some(s)` and other is `Some(o)`, this method returns `Some((s, o))`. Otherwise, `None` is returned. * * @example * const x = Some(1); * const y = Some("hi"); * const z = None<number>(); * * x.zip(y) === Some((1, "hi")); * x.zip(z) === None(); * @template U * @param {Option<U>} other * @throws `UndefinedBehaviorError` if `other` is not an instance of `Option` * @return {*} {Option<[Value, U]>} */ zip<const U, O extends Option<any, any> = Option<U>>(other: O): O extends Option<infer V, infer OS> ? OS extends typeof Status$1.Some ? S extends typeof Status$1.Some ? Option<[T, V], typeof Status$1.Some> : Option<[T, V], typeof Status$1.None> : Option<[T, V], typeof Status$1.None> : Option<[T, never], typeof Status$1.None>; /** * Zips self and another Option with function `f`. * * If self is `Some(s)` and other is `Some(o)`, this method returns `Some(f(s, o))`. Otherwise, `None` is returned. * * @example * class Point { * constructor (readonly x: number, readonly y: number){} * static create(x:number, y: number){ * return new Point(x,y); * } * } * const x = Some(17.5); * const y = Some(42.7); * * x.zipWith(y, Point.create) === Some({ x: 17.5, y: 42.7 }) * @throws `UndefinedBehaviorError` if `other` is not an instance of `Option` * @throws `UndefinedBehaviorError` if `predicate` is not a function * @template U * @template R * @param {Option<U>} other * @param predicate * @return {*} {Option<R>} */ zipWith<const U, const R, O extends Option<any, any> = Option<U>>(other: O, predicate: (value: T, other: O extends Option<infer V> ? V : U) => R): O extends Option<any, infer OS> ? OS extends typeof Status$1.Some ? S extends typeof Status$1.Some ? Option<R, typeof Status$1.Some> : Option<R, typeof Status$1.None> : Option<R, typeof Status$1.None> : Option<R, typeof Status$1.None>; /** * Unzips an option containing a tuple of two options. * * If self is `Some((a, b))` this method returns `(Some(a), Some(b))`. Otherwise, `(None, None)` is returned. * * @example * const x = Some([1, "hi"]); * const y = None<[number, number]>(); * console.assert(x.unzip() === [Some(1), Some("hi")]); * console.assert(y.unzip() === [None(), None()]); */ unzip(): T extends readonly [infer A, infer B] ? [Option<A, S>, Option<B, S>] : [Option<unknown, S>, Option<unknown, S>]; /** * Converts from `Option<Option<T>>` to `Option<T>`. * @example * const x: Option<Option<number>> = Some(Some(6)); * Some(6) === x.flatten(); * * const x: Option<Option<number>> = Some(None()); * None() === x.flatten(); * * const x: Option<Option<number>> = None(); * None() === x.flatten() * @return {*} {Value extends Option<infer Sub> ? Option<Sub> : Option<Value>} */ flatten(): T extends Option<infer Sub, infer SubStatus extends (typeof Status$1)[StatusKey$1]> ? Option<Sub, SubStatus> : Option<T, S>; /** * Some value of type `T`. */ static Some<const T = undefined>(value?: T): T extends undefined | null ? Option<T, typeof Status$1.None> : Option<NonNullable<T>, typeof Status$1.Some>; /** * No value. */ static None<T = undefined>(value?: undefined | null): Option<T, "None">; /** represents no value */ static none: typeof Option.None; /** represents some value (non `null` or `undefined`) */ static some: typeof Option.Some; /** * Creates an Option instance along with its associated `some` and `none` functions. * @returns An object containing the resolve function, reject function, and the Option instance. * @example * const { resolve, reject, option } = Option.withResolvers<number, string>(); * resolve(3); * option.then(value => console.log(value)); // Outputs: 3 */ static withResolvers<T>(): { some: SomeFn<T>; none: NoneFn<unknown>; option: Option<T, IsNever<T> extends true ? "None" : T extends undefined ? "None" : [T] extends [null] ? "None" : "None" | "Some">; }; static Status: Readonly<{ readonly None: "None"; readonly Some: "Some"; }>; /** * Returns `true` if incoming `value` is instance of `Option`. * * @static * @param {unknown} value * @return {*} * @memberof Ordering */ static is(value: unknown): boolean; /** * Await a promise and return an `Option` instance. * @param promiseLike promise to await * @returns */ static fromPromise<const P, const E>(promiseLike: P | Promise<P> | PromiseLike<P>): Promise<Option<Awaited<P>>>; static fromAsync: typeof Option.fromPromise; /** * Compare Self and another value. * You can pass your own function to compare * @example * const a = Some(2) * const b = 2 * const same = a.equal(b, (result, another) => { * // result = Some(2) * // another = 2 * return result.unwrap() === another * }) * console.log(same) // true * console.log(a.equal(b)) // false * console.log(a.equal(Some(2))) // true * @param other another value * @param [cmp=Object.is] compare function. Default - `Object.is` */ equal<const U = T, const Self extends Option<T, S> = this, const DefaultComparator extends ComparatorFn<any, any> = ComparatorFn<Self, U>, const ResolvedComparatorFn extends ComparatorFn<any, any> = U extends Option<infer UValue, any> ? ComparatorFn<T, UValue> : DefaultComparator>(other: U, cmp?: ResolvedComparatorFn): boolean; /** * Returns `true` if the option is a `Some` value. * * @example * const x: Option<number> = Some(2); * x.isSome() === true // true * * const x: Option<number> = None(); * x.isSome() === false // true * @return {*} {boolean} */ isSome(): S extends typeof Status$1.None ? false : S extends typeof Status$1.Some ? true : boolean; /** * Returns true if the option is a `None` value. * * @return {*} {boolean} */ isNone(): S extends typeof Status$1.None ? true : S extends typeof Status$1.Some ? false : boolean; /** * Returns `true` if the option is a `Some` and the value inside of it matches a predicate. * @throws `UndefinedBehaviorError` if predicate is not a function * @throws `UndefinedBehaviorError` if predicate return type is not a `boolean` * @example * const x: Option<number> = Some(2); * x.isSomeAnd(x => x > 1) === true // true * * const x: Option<number> = Some(0); * x.isSomeAnd(x => x > 1 ) === false // true * * const x: Option<number> = None(); * x.isSomeAnd(x => x > 1 ) === false // true * @param predicate */ isSomeAnd(predicate: (value: T) => boolean): boolean; /** * Inserts value into the option if it is `None`, then returns a mutable reference to the contained value. * * See also `insert`, which updates the value even if the option already contains `Some`. * @see {@link Option.insert insert method} * @throws `UndefinedBehaviorError` if incoming `value` is `null` or `undefined` * @example * const x = None<number>(); * const y = x.getOrInsert(7); * * y === 7 // true * @param {T} value * @return {*} {Value} */ getOrInsert<const U>(value: NonNullable<U>): S extends typeof Status$1.None ? U : T; /** * Inserts a value computed from `predicate` into the option if it is `None`, then returns the contained value. * @throws `UndefinedBehaviorError` if incoming `predicate` type is not a function * @throws `UndefinedBehaviorError` if incoming `predicate` returns `null` or `undefined` * @example * const x = None<number>(); * const y = x.getOrInsertWith(() => 5); * * y === 5 // true * * @param predicate * @return {*} {Value} */ getOrInsertWith<const U>(predicate: () => NonNullable<U>): S extends typeof Status$1.None ? U extends undefined ? never : U extends null ? never : U : T; /** * Returns the `Option` if it contains a value, otherwise returns `optb`. * Arguments passed to or are eagerly evaluated; if you are passing the result of a function call, it is recommended to use `orElse`, which is lazily evaluated. * * @throws `UndefinedBehaviorError` if incoming `optb` is not an instance of `Option` * @example * const x = Some(2); * const y = None(); * console.assert(x.or(y) === Some(2)); * // another example * const x = None(); * const y = Some(100); * console.assert(x.or(y) === Some(100)); * // another example * let x = Some(2) * let y = Some(100) * console.assert(x.or(y) === Some(2)); * // another example * const x: Option<number> = None(); * const y = None(); * console.assert(x.or(y) === None()); * * @param {Option<T>} optb * @return {*} {Option<Value>} */ or<const U, const O extends Option<any, any> = Option<U>>(optb: O): S extends typeof Status$1.None ? O : this; /** * Returns the `Option` if it contains a value, otherwise calls `f` and returns the result. * * @throws `UndefinedBehaviorError` if incoming `predicate` is not a function * @throws `UndefinedBehaviorError` if incoming `predicate` returns not an isntance of `Option` * @example * function nobody(): Option<string> { return None() } * function vikings(): Option<string> { return Some("vikings") } * * Some("barbarians").orElse(vikings) === Some("barbarians"); // true * None().orElse(vikings) === Some("vikings"); // true * None().orElse(nobody) === None(); // true * * @param predicate * @return {*} {Option<Value>} */ orElse<const U, const O extends Option<any, any> = Option<U>>(predicate: () => O): S extends typeof Status$1.None ? O : this; /** * Transposes an `Option` of a `Result` into a Result of an Option. * * `None` will be mapped to `Ok(None)`. * `Some(Ok(_))` and `Some(Err(_))` will be mapped to `Ok(Some(_))` and `Err(_)`. * @throws `UndefinedBehaviorError` if unwrapped value is not an instance of `Result` */ transpose(): T extends Result<infer OK, infer ERR> ? Result<Option<OK, S>, ERR> : S extends typeof Status$1.None ? Result<Option<T, S>, unknown> : never; /** * Returns raw value. * @note This method is used for internal purposes and should not be used directly. */ valueOf(): T | null | undefined; toString(): `${S}(${string})`; /** * This internal method using for `JSON.stringify` serialization. Please avoid using this method directly. * @internal * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#tojson_behavior MDN. toJSON behavior} */ toJSON(): { status: S | undefined; value: T | null | undefined; }; /** * @protected */ [Symbol.toPrimitive](): T | null | undefined; /** * @protected */ get [Symbol.toStringTag](): string; /** * @protected * Iterator support for `Option`. * * _Note: This method will only yeild if the Option is Some._ */ [Symbol.iterator](): S extends typeof Status$1.None ? never : T extends Iterable<infer TT> ? IteratorObject<TT, BuiltinIteratorReturn> : never; [Symbol.split]<const TError = TUndefinedBehaviorError<{ readonly message: `[Symbol.split] can applies only for Ok(<string>) value`; readonly cause: { readonly value: T; readonly status: S; readonly expectedType: string; }; readonly stack: ToStack<[ `Symbol.split`, `Status===Some: ${S extends typeof Status$1.Some ? true : false}` ]>; }>>(string: string, limit?: number): S extends typeof Status$1.None ? TError : T extends string ? string[] : TError; [Symbol.search]<const TError = TUndefinedBehaviorError<{ readonly message: "[Symbol.search] can applies only for Some(<string>) value"; readonly cause: { readonly value: T; readonly type: string; readonly status: S; }; }>>(string: string): S extends typeof Status$1.None ? TError : T extends string ? number : TError; /** * @protected * Iterator support for `Option`. * * _Note: This method will only yeild if the Option is Some._ */ [Symbol.asyncIterator](): S extends typeof Status$1.None ? never : T extends AsyncIterable<infer TT> ? AsyncIteratorObject<TT, BuiltinIteratorReturn> : never; [customInspectSymbol](depth: number, options: any, inspect: Function): string; } /** * Construct an `Option` from a value other than `None`. * @example * ```ts * function divide(left: number, right: number): Option<number> { * if (right === 0) return None(); * * return Some(left / right); * } * * ``` * * @example * ```ts * const foo = Some("Value"); * * if (foo instanceof Some) { * // Do something * } * ``` */ declare function Some<const T>(value?: T): T extends null | undefined ? Option<T, "None"> : Option<NonNullable<T>, "Some">; /** * Construct the None variant of Option. * * Can be initialized as `undefined` or `null` for optimization purpuses. * @default undefined * @example * ```ts * function divide(left: number, right: number): Option<number> { * if (right === 0) return None(); * * return Some(left / right); * } * ``` * @example * ```ts * const foo = None(); * * if (foo instanceof None) { * // Do something * } * ``` */ declare function None<const T>(value?: null | undefined): Option<T, "None">; /** MIT License Copyright (c) 2023 Vitali Haradkou Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** Result possible status */ declare const Status: Readonly<{ readonly Err: "Err"; readonly Ok: "Ok"; }>; type StatusKey = keyof typeof Status; type Resolver<T> = (value?: T) => void; type Rejecter<E> = (reason?: E) => void; type Executor<T, E, R = T> = (resolve: Resolver<T>, reject: Rejecter<E>) => R | void; /** * `Result<T, E>` is the type used for returning and propagating errors. It is an enum with the variants, `Ok(T)`, representing success and containing a value, and `Err(E)`, representing error and containing an error value. * * Based on Promise-like API * @template TInput success value * @template TErr error value * @throws `UndefinedBehaviorError` if executor is async function or returns a Promise * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/search implements Symbol.search} * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/split implements Symbol.split} * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator implements Symbol.iterator} * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator implements Symbol.asyncIterator} * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of for await of} syntax * @see {@link https://nodejs.org/api/util.html#utilpromisifycustom Node.js inspection symbol} implementation * @example * const r1 = new Result(() => { * throw new Error("qwe"); * }) * r1.isErr() // true * * const r2 = new Result(() => { * return "some success"; * }) * r2.isOk() // true * r2.unwrap() // "some success" * // using control flow functions * const r3 = new Result((ok, err) => { * // return is not needed * Math.random() > 0.5 ? ok("success") : err("error"); * }) * // Note: async functions or Promise return will throw an error * new Result(async () => { // throws * await Promise.resolve(); * }); * new Result(() => Promise.resolve()); // throws * Result.fromPromise(Promise.resolve('okay')); // OK. Result<okay> */ declare class Result<const TInput, const TErr = IsNever<TInput> extends true ? unknown : IsPromise<TInput> extends true ? TUndefinedBehaviorError<{ readonly message: `You passed an async function in constructor or executor returned a promise. Only synchronous functions are allowed. Use "Result.fromPromise" or "Result.fromAsync" instead.`; readonly cause: "AsyncFunction"; readonly stack: ToStack<["at new Result()", "at constructor"]>; }> : unknown, const S extends (typeof Status)[StatusKey] = IsNever<TInput> extends true ? typeof Status.Err : (typeof Status)[StatusKey]> { private value; private error; private status; constructor(executor: Executor<TInput, TErr>); /** * Returns the contained `Ok` value, consuming the self value. * * Because this function may throws, its use is generally discouraged. Call `unwrapOr`, `unwrapOrElse`. * * Panics if the value is an `Err`, with a message including the passed message, and the content of the `Err`. * * @example * const x: Result<number, string> = Err("emergency failure"); * x.expect("Testing expect"); // `Testing expect`, cause: emergency failure * @throws `Error` if `Result` has error status * @param {string} reason * @return {*} {T} */ expect(reason: string): S extends typeof Status.Err ? never : TInput; /** * Returns the contained `Ok` value, consuming the self value. * * Because this function may throws, its use is generally discouraged. Instead, call `unwrapOr`, `unwrapOrElse`. * * @example * const x: Result<number, string> = Ok(2); * x.unwrap() === 2; * @return {*} {T} */ unwrap(): S extends typeof Status.Err ? never : TInput; /** * Returns the contained `Ok` value or a provided default. * * Arguments passed to `unwrapOr` are eagerly evaluated; if you are passing the result of a function call, it is recommended to use `unwrapOrElse`, which is lazily evaluated. * * @example * const fallback = 2; * const x = Ok(9); * x.unwrapOr(fallback) === 9; // true * * cosnt x: Result<number, string> = Err("error"); * x.unwrapOr(fallback) === fallback; // true * @param {TInput} fallback * @return {*} {T} */ unwrapOr<const U>(fallback: U): S extends typeof Status.Err ? U : TInput; /** * Returns `true` if the result is `Ok`. * * @example * const x: Result<number, string> = Ok(-3); * x.isOk() // true * // another example * let x: Result<number, string> = Err("Some error message"); * x.isOk() // false * @return {*} {boolean} */ isOk(): [TInput] extends [never] ? false : S extends typeof Status.Ok ? true : S extends typeof Status.Err ? false : boolean; /** * Returns `true` if the result is `Ok` and the value inside of it matches a predicate. * * @throws `UndefinedBehaviorError` if `predicate` is not a function * @throws `UndefinedBehaviorError` if `predicate` result is not a boolean * @example * const x: Result<number, string> = Ok(2); * console.assert(x.isOkAnd(x => x > 1) === true); * // another example * const x: Result<number, string> = Ok(0); * console.assert(x.isOkAnd(x => x > 1) === false); * // another example * const x: Result<number, string> = Err("hey"); * console.assert(x.isOkAnd(x => x > 1) === false); * @return {*} {boolean} */ isOkAnd<const R extends boolean>(predicate: (value: TInput) => R): S extends typeof Status.Ok ? true : R; /** * Returns `true` if the result is `Err`. * * @example * const x: Result<number, string> = Ok(-3); * console.assert(x.isErr() === false); * // another example * const x: Result<number, string> = Err("Some error message"); * console.assert(x.isErr() === true); * * @return {*} {boolean} */ isErr(): IsNever<TInput> extends true ? true : S extends typeof Status.Err ? true : S extends typeof Status.Ok ? false : boolean; /** * Returns `true` if the result is `Err` and the value inside of it matches a predicate. * @example * const x: Result<number, Error> = Err(new Error("not found")); * x.isErrAnd(e => e.message === 'not found') // true; * // another example * const x: Result<number, Error> = Err(new Error('permission denied')); * x.isErrAnd(x => x.name === 'TypeError') // false * // another example * const x: Result<number, Error> = Ok(123); * x.isErrAnd(e => e.name == 'Error'); // false * @throws `UndefinedBehaviorError` if `predicate` is not a function * @throws `UndefinedBehaviorError` if `predicate` result is not a boolean * @param {(err: TErr) => boolean} predicate * @return {*} {boolean} */ isErrAnd<const R extends boolean, const PredicateFn extends Fn<R, [err: TErr]> = Fn<R, [err: TErr]>>(predicate: PredicateFn): S extends typeof Status.Err ? true : R; /** * Converts from `Result<T, E>` to `Option<T>`. * * Converts self into an `Option<T>`, consuming self, and discarding the error, if any. * * @example * const x: Result<number, string> = Ok(2); * x.ok() === Some(2); // true * // another example * const x: Result<number, string> = Err("Nothing here"); * x.ok() === None(); // true * @return {*} {Option<T>} */ ok(): S extends typeof Status.Ok ? Option<TInput, typeof Option.Status.Some> : Option<TInput, typeof Option.Status.None>; /** * Converts from `Result<T, E>` to `Option<E>`. * * Converts self into an `Option<E>`, consuming self, and discarding the success value, if any. * * @example * const x: Result<number, string> = Ok(2); * x.err() === None(); // true * * const x: Result<number, string> = Err("Nothing here"); * x.err() === Some("Nothing here"); // true * @return {*} {Option<E>} */ err(): S extends typeof Status.Err ? Option<TErr, typeof Option.Status.Some> : Option<TErr, typeof Option.Status.None>; /** * Maps a `Result<T, E>` to `Result<U, E>` by applying a function to a contained Ok value, leaving an `Err` value untouched. * * This function can be used to compose the results of two functions. * * @example * const x = Ok(1); * x.map(v => v * 2) === Ok(2) // true * * @template U * @throws `UndefinedBehaviorError` if `mapFn` is not a function * @param {(value: TInput) => U} mapFn * @return {*} {Result<U, E>} */ map<const U>(mapFn: (value: TInput) => U): S extends typeof Status.Err ? this : Result<U, TErr>; /** * Returns the provided default (if `Err`), or applies a function to the contained value (if `Ok`), * * Arguments passed to `mapOr` are eagerly evaluated; if you are passing the result of a function call, it is recommended to use `mapOrElse`, which is lazily evaluated. * * @example * const x: Result<string, string> = Ok("foo"); * x.mapOr(42, v => v.length) // result is 3 * // another example * const x: Result<number, string> = Err("bar"); * x.mapOr(42, v => v.length) // 42 * @throws `UndefinedBehaviorError` if `predicate` is not a function * @template U * @param {U} another * @param {(value: TInput) => U} predicate * @return {*} {U} */ mapOr<const U, const FR>(another: U, predicate: (value: TInput) => FR): S extends typeof Status.Err ? U : FR; /** * Maps a `Result<T, E>` to `U` by applying fallback function default to a contained `Err` value, or function `f` to a contained `Ok` value. * * This function can be used to unpack a successful result while handling an error. * * @example * let k = 21; * * const x: Result<string, string> = Ok("foo"); * x.mapOrElse(err => k * 2, v => v.length); // 3 * * const y : Result<string, string> = Err("bar"); * y.mapOrElse(e => k * 2, v => v.length) // 42 * @throws `UndefinedBehaviorError` if `errFn` is not a function * @throws `UndefinedBehaviorError` if `okFn` is not a function * @template U * @param errFn * @param okFn * @return {*} {U} */ mapOrElse<const ER, const RR>(errFn: (err: TErr) => ER, okFn: (value: TInput) => RR): S extends typeof Status.Err ? ER : RR; /** * Maps a `Result<T, E>` to `Result<T, F>` by applying a function to a contained `Err` value, leaving an `Ok` value untouched. * * This function can be used to pass through a successful result while handling an error. * * @example * const stringify = (x: number) => `error code: ${x}` * * const x: Result<number, number> = Ok(2); * x.mapErr(stringify) === Ok(2) // true * * const y: Result<number, number> = Err(13); * y.mapErr(stringify) === Err("error code: 13")); * @template F * @throws `UndefinedBehaviorError` if `errFn` is not a function * @param {(err: TErr) => F} errFn * @return {*} {Result<T, F>} */ mapErr<const F>(errFn: (err: TErr) => F): S extends typeof Status.Err ? Result<TInput, F> : this; /** * Returns the contained `Err` value, consuming the self value. * * @example * const x: Result<number, string> = Ok(10); * x.expectErr("Testing expectErr"); // throws `Testing expectErr; cause: 10` * @throws `Error` if `Result` status is OK * @param {string} reason * @return {*} {E} */ expectErr(reason: string): S extends typeof Status.Ok ? never : TErr; /** * Returns the contained `Err` value, consuming the self value. * * @example * const x: Result<number, string> = Err("emergency failure"); * x.unwrapErr() === "emergency failure"; * @throws `value` if `Result` status is OK * @return {*} {E} */ unwrapErr(): S extends typeof Status.Err ? TErr : never; /** * Returns the contained `Ok` value or computes it from a closure. * * @example * const count = (x: string) => x.length; * * Ok(2).unwrapOrElse(count) === 2 // true * Err("foo").unwrapOrElse(count) === 3; // true * @throws `UndefinedBehaviorError` if `predicate` is not a function * @param predicate * @return {*} {T} */ unwrapOrElse<const U>(predicate: (err: TErr) => U): S extends typeof Status.Ok ? TInput : U; /** * Returns `res` if the result is `Ok`, otherwise returns the `Err` value of self. * * Arguments passed to and are eagerly evaluated; if you are passing the result of a function call, it is recommended to use `andThen`, which is lazily evaluated. * * @example * const x: Result<number, string> = Ok(2); * const y: Result<string, string> = Err("late error"); * x.and(y) === Err("late error"); // true * // another example * const x: Result<number, string> = Err("early error"); * const y: Result<string, string> = Ok("foo"); * x.and(y) === Err("early error"); // true * // another example * const x: Result<number, string> = Err("not a 2"); * const y: Result<string, string> = Err("late error"); * x.and(y) === Err("not a 2"); // true * // another example * const x: Result<number, string> = Ok(2); * const y: Result<string, string> = Ok("different result type"); * x.and(y) === Ok("different result type"); // true * @template U * @throws `UndefinedBehaviorError` if `res` is not an instance of `Result` * @param res * @return {*} {Result<U, E>} */ and<const U, const R extends Result<any, any, any>>(res: R): S extends typeof Status.Ok ? R extends Result<any, infer RE, infer RS> ? RS extends typeof Status.Ok ? R : Result<U, RE, RS> : Result<TInput, TErr, S> : S extends typeof Status.Err ? Result<TInput, TErr, S> : R extends Result<any, infer RE, infer RS> ? Result<U, RE, RS> : Result<TInput, TErr>; /** * Calls op if the result is `Ok`, otherwise returns the `Err` value of self. * * This function can be used for control flow based on `Result` values. * * @example * const sqThenToString = (x: number) => { * return Ok(x * x).map(sq => sq.toString()) * } * * Ok(2).andThen(sqThenToString) === Ok(4.toString())); // true * Err("not a number").andThen(sqThenToString) === Err("not a number"); // true * @template U * @throws `UndefinedBehaviorError` if `fn` argument is not a function * @throws `UndefinedBehaviorError` if `fn` result is not an instance of `Result` * @param {(value: TInput) => Result<U, TErr>} fn * @return {*} {Result<U, E>} */ andThen<const U, const R extends Result<any, any, any> = Result<U, TErr, any>>(fn: (value: TInput) => R): S extends typeof Status.Err ? this : R; /** * Returns `res` if the result is `Err`, otherwise returns the `Ok` value of self. * * Arguments passed to or are eagerly evaluated; if you are passing the result of a function call, it is recommended to use `orElse`, which is lazily evaluated. * * @example * const x: Result<number, string> = Ok(2); * const y: Result<number, string> = Err("late error"); * x.or(y) === Ok(2); // true * // another example * const x: Result<number, string> = Err("early error"); * const y: Result<number, string> = Ok(2); * x.or(y) === Ok(2); // true * // another example * const x: Result<number, string> = Err("not a 2"); * const y: Result<number, string> = Err("late error"); * x.or(y) === Err("late error"); // true * // another example * const x: Result<number, string> = Ok(2); * const y: Result<number, string> = Ok(100); * x.or(y) === Ok(2); // true * @template F * @throws `UndefinedBehaviorError` if `res` argument is not an instance of `Result` * @param {Result<TInput, F>} res * @return {*} {Result<T, F>} */ or<const F, const R extends Result<any, any, any> = Result<any, F, any>>(res: R): S extends typeof Status.Err ? R : Result<TInput, F, S>; /** * Calls `fn` if the result is `Err`, otherwise returns the `Ok` value of self. * * This function can be used for control flow based on result values. * * @example * const sq = (x: number) => Ok(x * x); * const err = (x: number) => Err(x); * * Ok(2).orElse(sq).orElse(sq) === Ok(2); // true * Ok(2).orElse(err).orElse(sq) === Ok(2); // true * Err(3).orElse(sq).orElse(err) === Ok(9); // true * Err(3).orElse(err).orElse(err) === Err(3); // true * @throws `UndefinedBehaviorError` if `fn` argument is not a function * @throws `UndefinedBehaviorError` if `fn` result is not an instance of `Result` * @param fn * @return {*} {Result<T, F>} */ orElse<const R extends Result<any, any, any> = Result<any, any, any>>(fn: (err: TErr) => R): S extends typeof Status.Ok ? this : R; /** * Converts from `Result<Result<T, E>, E>` to `Result<T, E>` * * @example * const x: Result<Result<string, number>, number> = Ok(Ok("hello")); * Ok("hello") === x.flatten() // true * * const x: Result<Result<string, number>, number> = Ok(Err(6)); * Err(6) === x.flatten(); // true * * const x: Result<Result<string, number>, number> = Err(6); * Err(6) === x.flatten(); // true * @return {*} {T extends Result<infer Ok, E> ? Result<Ok, E> : Result<T, E>} */ flatten(): TInput extends Result<infer Ok, TErr> ? Result<Ok, TErr> : Result<TInput, TErr>; static Ok<const V, const E>(value: V): Result<V, E, "Ok">; static Err<const V, const ErrorValue>(value: ErrorValue): Result<V, ErrorValue, "Err">; static ok: typeof Result.Ok; static err: typeof Result.Err; /** * Similar to `Promise.withResolvers` API. * @example * const {ok, result} = Result.withResolvers() * ok(3) * result.unwrap() // 3 * result.isOk() // true * */ static withResolvers<const T, const E>(): { ok: Resolver<T>; err: Rejecter<E>; result: Result<T, E, IsNever<T> extends true ? "Err" : "Err" | "Ok">; }; /** * Returns `true` if incoming `value` is instance of `Result`. * * @static * @param {unknown} value * @return {*} * @memberof Ordering */ static is(value: unknown): boolean; static Status: Readonly<{ readonly Err: "Err"; readonly Ok