UNPKG

@dancrumb/fpish

Version:

FP-friendly classes for Typescript

130 lines (129 loc) 4.73 kB
import { Optional } from './Optional.js'; /** * The `Either<R,L>` type represents 2 possible values of 2 possible types. * * A common use case it to use this to represent the outcome of a function that could * be an error or a value: `const result: Either<ErrorType, ValueType>`. Convention has * `ErrorType` as the left-value and `ValueType` as the right-value. * * The type will only ever be single-valued, but it will always be single-valued */ export declare class Either<L, R> { /** * Create a Left-valued `Either` * @param value */ static left<NL, NR>(value: NL | Optional<NL>): Either<NL, NR>; /** * Create a Right-valued `Either` * @param value */ static right<NL, NR>(value: NR | Optional<NR>): Either<NL, NR>; private readonly left; private readonly right; constructor(l: Optional<L>, r: Optional<R>); /** * Returns whether or not the value is left-valued */ isLeft(): boolean; /** * Gets the left-value of the object. * * This will result in an error, if the object is not left-valued * * @throws {NoSuchElementException} */ getLeft(): L; /** * Returns whether or not the value is right-valued */ isRight(): boolean; /** * Gets the right-value of the object. * * This will result in an error, if the object is not right-valued * * @throws {NoSuchElementException} */ getRight(): R; /** * Maps the `Either<L,R>` object to a simple object of type `T`. * * Each of the mapping functions must return the same type, so that this `Either` object can * be mapped. * * Only one of the functions will be called, so no side-effects should be relied upon. * * @param lFunc * @param rFunc */ map<O>(lFunc: (val: L) => O | Optional<O>, rFunc: (val: R) => O | Optional<O>): O; map<T>(lFunc: (val: L) => T, rFunc: (val: R) => T): T; /** * Map the left-value of one type to a different value of another type. * * If this object is right-valued, then this doesn't change that, but it does * change the overall type of the `Either` object * * @param lFunc */ mapLeft<O>(lFunc: (val: L) => Optional<O>): Either<O, R>; mapLeft<T>(lFunc: (val: L) => T): Either<T, R>; /** * Map the right-value of one type to a different value of another type. * * If this object is leftt-valued, then this doesn't change that, but it does * change the overall type of the `Either` object * * @param rFunc */ mapRight<O>(rFunc: (val: R) => Optional<O>): Either<L, O>; mapRight<T>(rFunc: (val: R) => T): Either<L, T>; /** * Much like `{@link mapLeft}`, this converts an `Either` from one type to another. * * The difference here is that the mapping function returns an `Either` of its own, rather * than just a left-value. This allows you to chain a series of `Either`s together, only operating * if you are getting left-valued `Either`s * * @param lFunc */ proceedLeft<T>(lFunc: (val: L) => Either<T, R>): Either<T, R>; proceedLeft<T>(lFunc: (val: L) => Promise<Either<T, R>>): Promise<Either<T, R>>; /** * Much like `{@link mapRight}`, this converts an `Either` from one type to another. * * The difference here is that the mapping function returns an `Either` of its own, rather * than just a right-value. This allows you to chain a series of `Either`s together, only operating * if you are getting right-valued `Either`s * * @param rFunc */ proceedRight<T>(rFunc: (val: R) => Either<L, T>): Either<L, T>; proceedRight<T>(rFunc: (val: R) => Promise<Either<L, T>>): Promise<Either<L, T>>; /** * Collapses an `Either` that may contain a left-value that is an `Either` * @param either */ static joinLeft<JL, JR>(either: Either<Either<JL, JR>, JR>): Either<JL, JR>; /** * Collapses an `Either` that may contain a right-value that is an `Either` * @param either */ static joinRight<JL, JR>(either: Either<JL, Either<JL, JR>>): Either<JL, JR>; /** * Applies a function to the internal value. Since this returns void and takes functions that return * void, this relies entirely on side-effects.. * @param lFunc * @param rFunc */ apply(lFunc: (val: L) => void, rFunc: (val: R) => void): this; /** * Runs the provided function if the left value is populated */ ifLeft(lFunc: (val: L) => void): this; /** * Runs the provided function if the right value is populated */ ifRight(rFunc: (val: R) => void): this; }