/**
 * A Result indicating success.
 */
export type OkResult<Ok> = {
    ok: Ok;
    isOkay: true;
    match: typeof match;
    expect: typeof expect;
};
/**
 * A Result indicating failure.
 */
export type ErrorResult<Error = ResultError> = {
    error: Error;
    isOkay: false;
    match: typeof match;
    /**
     * Add context to an action result as it is passed down the stack.
     */
    elaborate: typeof elaborate;
    expect: typeof expect;
};
/**
 * The result is a Result type that can be used for any interface that
 * carries out a failable action. The idea being that any errors will be
 * caught be the implementation of the interface and documented in an `ResultError`.
 * This means that interfaces do not need to depend on the exact interface of
 * any Errors and Exceptions that can be thrown by an implementation.
 * As it is often impossible to know their interface.
 * Additionally, this also provides a consistent way to describe what went wrong
 * to a user of the application that can also be referenced in log files.
 *
 * @typeParam Ok The result if the action was a success.
 * @typeParam Error The result if the action was a failure.
 * @see {@link Ok}
 * @see {@link isOk}
 * @see {@link ResultError}
 * @see {@link isError}
 */
export type Result<Ok, Error = ResultError> = OkResult<Ok> | ErrorResult<Error>;
/**
 * @param ok The value indicating a successful result.
 * @returns Return an Result that was a success with the value ok.
 */
export declare function Ok<Ok>(ok: Ok): Result<Ok, never>;
/**
 * @param error The value indicating a failed result.
 * @returns An `Result` that was a failure with the error value.
 */
export declare function Err<Error>(error: Error): Result<never, Error>;
/**
 * Check an `Result` was a success, can be used as a type assertion.
 * @param result An `Result` to check the success of.
 * @returns `true` if the `Result` was a success.
 */
export declare function isOk<Ok, Error = ResultError>(result: Result<Ok, Error>): result is OkResult<Ok>;
/**
 * Check an `Result` was a failure, can be used as a type assertion.
 * @param result The `Result` to check the success of.
 * @returns `true` if the `Result` was a failure.
 */
export declare function isError<Ok, Error = ResultError>(result: Result<Ok, Error>): result is ErrorResult<Error>;
declare function elaborate<Error extends ResultError = ResultError>(this: ErrorResult<Error>, message: string): ErrorResult<Error>;
declare function match<T, Ok, Error = ResultError>(this: Result<Ok, Error>, ok: (ok: Ok) => T, error: (error: Error) => T): T;
type ExtractOk<T> = T extends OkResult<infer Ok> ? Ok : never;
export declare function ExpectError<TResult extends Result<unknown>>(result: TResult, elaboration: string): TResult extends ErrorResult ? never : ExtractOk<TResult>;
declare function expect<TResult extends Result<unknown>>(this: TResult, elaboration: string): TResult extends ErrorResult ? never : ExtractOk<TResult>;
/**
 * An extensible representation of an Error that describes what went wrong in a
 * a standard way.
 * @see {@link ActionException}
 */
export declare class ResultError {
    readonly message: string;
    private readonly elaborations;
    constructor(message: string, elaborations?: string[]);
    /**
     * Convienant factory method to wrap an `ResultError` into an `Result`.
     * @param message The message for the `ResultError` that concisely describes the problem.
     * @param _options This exists so that the method is extensible by subclasses.
     * Otherwise they wouldn't be able to pass other constructor arguments through this method.
     * @returns An `Result` with a `ResultError` as the `Error` value.
     */
    static Result(message: string, _options?: {}): Result<never>;
    /**
     * Elaborate on an ResultError that has been passed down the call stack.
     * Since we may need to offer a better explanation in a higher level context.
     * For example, there may be an ActionException relating to a network error,
     * but there is no explanation for what the caller was attempting to do.
     * So we can use this in the caller code to elaborate on the error.
     * @param message A short message to contextualise the action,
     * For example: "Failed to join the provided policy room.".
     * @returns This ResultError.
     */
    elaborate(message: string): this;
    getElaborations(): string[];
    get mostRelevantElaboration(): string;
    toReadableString(): string;
    toString(): string;
    toExpectError(): Error;
}
export {};
//# sourceMappingURL=Result.d.ts.map