import { ResultAsync } from './resultAsync.js'; import { Unit } from './unit.js'; import { Action, ActionOfT, AsyncAction, AsyncActionOfT, ErrorHandler, FunctionOfT, FunctionOfTtoK, None, Predicate, PredicateOfT, ResultMatcher, ResultMatcherNoReturn, Some } from './utilities.js'; /** * Allows to extract the Value of the given `Result` or `ResultAsync` * * @example ResultValue> => string * @example ResultValue> => string */ export type ResultValue = T extends Result ? TResultValue : T extends ResultAsync ? TResultAsyncValue : never; export type ResultRecord = { [K in keyof TResultRecord]: ResultValue; }; /** * Represents a successful Result operation. */ type ResultSuccess = Result & { value: TValue; }; /** * Represents a failed Result operation. */ type ResultFailure = Result & { error: TError; }; /** * Represents a successful or failed operation */ export declare class Result { /** * Combines several results (and any error messages) into a single result. * The returned result will be a failure if any of the input results are failures. * * @param results The Results to be combined. * @returns A Result that is a success when all the input results are also successes. */ static combine>>(results: TResultRecord): Result>; static combineAsync | ResultAsync>>(record: TResultRecord): ResultAsync>; static combineInOrderAsync | ResultAsync>>(record: TResultRecord): ResultAsync>; /** * Creates a new successful Result with a string error type * and Unit value type */ static success(): Result; /** * Creates a new successful Result with the given value * @param value the result of the successful operation */ static success(value: Some): Result; static successIf(condition: boolean, state: { value: Some; error: Some; }): Result; static successIf(predicate: Predicate, state: { value: Some; error: Some; }): Result; /** * Creates a new failed Result * @param error the error of the failed operation * @returns new failed Result */ static failure(error: Some): Result; static failureIf(condition: boolean, state: { value: Some; error: Some; }): Result; static failureIf(predicate: Predicate, state: { value: Some; error: Some; }): Result; /** * Returns only the values of successful Results * @param results */ static choose(results: Result[]): TValue[]; /** * Returns only the values of successful Results, mapped to new values * with the given selector function * @param results * @param projection */ static choose(results: Result[], projection: FunctionOfTtoK): TNewValue[]; /** * Creates a new successful Result with the return value * of the given factory function. If the function throws, a failed Result will * be returned with an error created by the provided errorHandler * @param factory * @param errorHandler */ static try(factory: FunctionOfT>, errorHandler: ErrorHandler): Result; /** * Creates a new successful Result with a Unit value. * If the function throws, a failed Result will * be returned with an error created by the provided errorHandler * @param action * @param errorHandler */ static try(action: Action, errorHandler: ErrorHandler): Result; /** * True if the result operation succeeded */ get isSuccess(): boolean; /** * True if the result operation failed. */ get isFailure(): boolean; /** * Yields value if the result operation succeeded. * Hint: Use hasValue() upfront to be sure that result operation succeeded. */ protected get value(): Some | undefined; /** * Yields error if the result operation failed. * Hint: Use hasError() upfront to be sure that result operation failed. */ protected get error(): Some | undefined; /** * Checks if result operation succeeded. */ hasValue(): this is ResultSuccess; /** * Checks if result operation failed. */ hasError(): this is ResultFailure; /** * The internal state of the Result */ private state; /** * Creates a new Result instance in a guaranteed valid state * @param {{ value?: TValue, error?: TError, isSuccess: boolean }} state the initial state of the Result * @throws {Error} if the provided initial state is invalid */ protected constructor(state: { value: Some | None; error: Some | None; isSuccess: boolean; }); /** * Gets the Result's inner value * @returns {TValue} the inner value if the result suceeded * @throws {Error} if the result failed */ getValueOrThrow(): Some; /** * Returns the Result's value if it is successful and the default otherwise * @param defaultValue a value to return if the Result is failed */ getValueOrDefault(defaultValue: Some): Some; /** * Returns the Result's value if it is successful and the evaluation of the factory function otherwise * @param factory a function which is executed and returned if the Result is failed */ getValueOrDefault(factory: FunctionOfT>): Some; /** * Gets the Result's inner error * @returns {TError} the inner error if the operation failed * @throws {Error} if the result succeeded */ getErrorOrThrow(): Some; /** * Gets the Result's inner error * @param defaultOrErrorFactory An error or error creator function * @returns {TError} The Result's error or a default error if the Result succeeded */ getErrorOrDefault(error: Some): Some; getErrorOrDefault(errorFactory: FunctionOfT>): Some; /** * If the Result has failed, the result is returned. * Otherwise, it executes the predicate and returns a failed Result with the given error * if the predicate returns false, and the current Result if it returns true * @param predicate check against the Result's inner value * @param error An error for the returned Result if the predicate returns false */ ensure(predicate: PredicateOfT, error: Some): Result; /** * If the Result has failed, the result is returned. * Otherwise, it executes the predicate and returns a failed Result with an error created from the errorFactory * if the predicate returns false, and the current Result if it returns true * @param predicate check against the Result's inner value * @param errorFactory A function provided the Result's value, used to create an error for the returned Result if the predicate returns false */ ensure(predicate: PredicateOfT, errorFactory: FunctionOfTtoK>): Result; /** * Returns a successful Result with the current value if the projection returns a successful Result * @param projection a function given the current Result's value and returns a new Result * @returns If the Result has failed, it is returned. Otherwise, the projection is executed. * If the projection returns a successful Result, a successful Result with the original value is returned. * If the projection returns a failed Result it is returned. */ check(projection: FunctionOfTtoK>): Result; /** * Similar to check, but the projection is only executed if the Result has succeeded and the condition is true * @param condition * @param projection */ checkIf(condition: boolean, projection: FunctionOfTtoK>): Result; /** * Similiar to check, but the projection is only executed if the Result has succeeded and the predicate returns true * @param predicate * @param projection */ checkIf(predicate: PredicateOfT, projection: FunctionOfTtoK>): Result; pipe(): Result; pipe(op1: ResultOpFnAsync): ResultAsync; pipe(op1: ResultOpFn): Result; pipe(op1: ResultOpFn, op2: ResultOpFnAsync): ResultAsync; pipe(op1: ResultOpFn, op2: ResultOpFn): Result; pipe(op1: ResultOpFn, op2: ResultOpFn, op3: ResultOpFnAsync): ResultAsync; pipe(op1: ResultOpFn, op2: ResultOpFn, op3: ResultOpFn): Result; pipe(op1: ResultOpFn, op2: ResultOpFn, op3: ResultOpFn, op4: ResultOpFnAsync): ResultAsync; pipe(op1: ResultOpFn, op2: ResultOpFn, op3: ResultOpFn, op4: ResultOpFn): Result; pipe(op1: ResultOpFn, op2: ResultOpFn, op3: ResultOpFn, op4: ResultOpFn, op5: ResultOpFnAsync): ResultAsync; pipe(op1: ResultOpFn, op2: ResultOpFn, op3: ResultOpFn, op4: ResultOpFn, op5: ResultOpFn): Result; pipe(op1: ResultOpFn, op2: ResultOpFn, op3: ResultOpFn, op4: ResultOpFn, op5: ResultOpFn, op6: ResultOpFnAsync): ResultAsync; pipe(op1: ResultOpFn, op2: ResultOpFn, op3: ResultOpFn, op4: ResultOpFn, op5: ResultOpFn, op6: ResultOpFn): Result; pipe(op1: ResultOpFn, op2: ResultOpFn, op3: ResultOpFn, op4: ResultOpFn, op5: ResultOpFn, op6: ResultOpFn, op7: ResultOpFnAsync): ResultAsync; pipe(op1: ResultOpFn, op2: ResultOpFn, op3: ResultOpFn, op4: ResultOpFn, op5: ResultOpFn, op6: ResultOpFn, op7: ResultOpFn): Result; pipe(op1: ResultOpFn, op2: ResultOpFn, op3: ResultOpFn, op4: ResultOpFn, op5: ResultOpFn, op6: ResultOpFn, op7: ResultOpFn, op8: ResultOpFnAsync): ResultAsync; pipe(op1: ResultOpFn, op2: ResultOpFn, op3: ResultOpFn, op4: ResultOpFn, op5: ResultOpFn, op6: ResultOpFn, op7: ResultOpFn, op8: ResultOpFn): Result; /** * Maps the value successful Result to a new value * @param projection a function given the value of the current Result which returns a new value * @returns If the Result has failed, a new one with the same error is returned. * Otherwise a new successful Result is returned with the value of the projection. */ map(projection: FunctionOfTtoK>): Result; /** * Maps the error of a failed Result to a new error * @param projection a function given the error of the current Result which returns a new error * @returns If the Result has succeeded, a new one with the same value is returned. * Otherwise a new failed Result is returned with the error created by the projection. */ mapError(projection: FunctionOfTtoK>): Result; /** * Converts a failed Result into a successful one * @param projection a function that maps the error of the current Result to a value * @returns A successful Result using the current Result's value if it succeeded and the projection's value if it failed */ mapFailure(projection: FunctionOfTtoK>): Result; /** * Maps the value successful Result to a new async value wrapped in a ResultAsync * @param projection a function given the value of the current Result which returns a Promise of some value * @returns */ mapAsync(projection: FunctionOfTtoK>>): ResultAsync; /** * Maps the error of a failed Result to a new async value wrapped in a ResultAsync * @param projection a function given the error of the current Result which returns a Promise of some value * @returns */ mapFailureAsync(projection: FunctionOfTtoK>>): ResultAsync; /** * Maps a successful Result to a new Result * @param projection a function given the value of the current Result which returns a new Result of some value * @returns */ bind(projection: FunctionOfTtoK>): Result; /** * Maps a successful Result to a new ResultAsync * @param projection */ bindAsync(projection: FunctionOfTtoK>>): ResultAsync; /** * Maps a successful Result to a new ResultAsync * @param projection */ bindAsync(projection: FunctionOfTtoK>): ResultAsync; /** * Maps a failed Result to a new Result * @deprecated Please use `compensate` instead * @param projection * @returns */ bindFailure(projection: FunctionOfTtoK>): Result; /** * Maps a failed Result to a new Result * @param projection * @returns */ compensate(projection: FunctionOfTtoK>): Result; /** * Maps a failed Result to a new ResultAsync * @deprecated Please use `compensateAsync` instead * @param projection * @returns */ bindFailureAsync(projection: FunctionOfTtoK> | ResultAsync>): ResultAsync; /** * Maps a failed Result to a new ResultAsync * @param projection * @returns */ compensateAsync(projection: FunctionOfTtoK> | ResultAsync>): ResultAsync; /** * Executes an action if the current Result has succeeded * @param action a function given the value of the current Result * @returns the current Result */ tap(action: ActionOfT): Result; /** * Executes an action if the current Result has failed * @param action a function given the error of the current Result * @returns the current Result */ tapFailure(action: ActionOfT): Result; /** * Executes an async action if the Result succeeded * @param action a function given the Result's value returns a Promise * @returns a ResultAsync */ tapAsync(action: AsyncActionOfT): ResultAsync; /** * Executes an action if the given condition is true and the Result has succeeded * @param condition a boolean value * @param action a function given the Result's value * @returns the current Result */ tapIf(condition: boolean, action: ActionOfT): Result; /** * Executes and action if the given predicate evaluates to true and the Result has succeeded * @param predicate a function given the Result's value and returns a boolean * @param action a function given the Result's value * @returns the current Result */ tapIf(predicate: PredicateOfT, action: ActionOfT): Result; /** * Executes the action on both success and failure. * @param action a function with no parameters returning no value * @returns the current Result */ tapEither(action: Action): Result; /** * Executes the asynchronous action on both success and failure. * @param action a function * @returns the current Result wrapped in a ResultAsync */ tapEitherAsync(action: AsyncAction): ResultAsync; /** * Maps a successful Result's value to a new value, * or a failed Result's error to a new value * @param matcher */ match(matcher: ResultMatcher): TNewValue; /** * Executes an action for a Result in either the successful and failed state * @param matcher */ match(matcher: ResultMatcherNoReturn): Unit; /** * Executes the same function for both failed and successful Results * @param projection * @returns */ finally(projection: FunctionOfTtoK, Some>): Some; /** * * @param action * @param errorHandler * @returns */ onSuccessTry(action: ActionOfT, errorHandler: ErrorHandler): Result; /** * * @param asyncAction * @param errorHander * @returns */ onSuccessTryAsync(asyncAction: FunctionOfTtoK>, errorHander: ErrorHandler): ResultAsync; /** * Returns a string representation of the Result state (success/failure) * @returns */ toString(): string; debug(): string; equals(result: Result): boolean; } export type ResultOpFn = FunctionOfTtoK, Result>; export type ResultOpFnAsync = FunctionOfTtoK, ResultAsync>; export {};