/**
 * Interface for the Result type.
 */
interface ResultBase<T, TErr> {
    /**
     * A type guard that checks if this Result is Ok. If it is, the Result is cast to Ok.
     * @returns true if this Result is Ok, false otherwise.
     */
    isOk(): this is Ok<T>;
    /**
     * A type guard that checks if this Result is Err. If it is, the Result is cast to Err.
     * @returns true if this Result is Err, false otherwise.
     */
    isErr(): this is Err<TErr>;
    /**
     * Calls the provided function with the contained value if this Result is Ok.
     * Nothing is performed otherwise.
     *
     * @param f - The function to be called if this Result is Ok. First arg will receive the contained value.
     *
     * @returns This Result.
     */
    inspect(f: (value: T) => unknown): this;
    /**
     * Calls the provided function with the contained value if this Result is Err.
     * Nothing is performed otherwise.
     *
     * @param f - The function to be called if this Result is Err. First arg will receive the contained error.
     *
     * @returns This Result.
     */
    inspectErr(f: (error: TErr) => unknown): this;
    /**
     * If this Result is Ok, calls the given mapper function with the current contained value
     *  and returns a new Result containing the value returned by the mapper function.
     *
     * @param mapper - The function that maps the current contained value to another value.
     *
     * @returns A new Result object containing the value returned by the mapper function, or this if this is Err.
     */
    map<TNew>(mapper: (value: T) => TNew): this | Result<TNew, TErr>;
    /**
     * If this Result is Ok, it does the same thing as {@link map}.
     * Otherwise, returns the given default value.
     *
     * @param def -  The default value to be returned if this Result is Err.
     * @param mapper - The function that maps the current contained value to another value if this Result is Ok.
     *
     * @returns A new Result object containing the value returned by the mapped function if this is Ok, otherwise the default value.
     */
    mapOr<TNew, TDef>(def: TDef, mapper: (value: T) => TNew): TNew | TDef;
    /**
     * Same as {@link mapOr}, except if this is Err, the default value is returned lazily by the first callback
     * which receives the contained error and returns the default value.
     *
     * @param errMapper - The function that maps the contained error value to a default value if this Result is Err.
     * @param mapper - The function that maps the contained value to a new value if this Result is Ok.
     *
     * @returns The value returned by the error mapper if this is Err; The value returned by the value mapper if this is Ok.
     */
    mapOrElse<TNew, TDef>(errMapper: (error: TErr) => TDef, mapper: (value: T) => TNew): TNew | TDef;
    /**
     * If this Result is Err, calls the given mapper with the current error value,
     * then returns a new Result containing the new error value returned by the mapper.
     * Otherwise, nothing is performed and this is returned.
     *
     * @param mapper - The function that maps the contained error value to another error value.
     *
     * @returns A new Result containing the error value returned by the mapper if this is Err, or this Result otherwise.
     */
    mapErr<TNewErr>(mapper: (error: TErr) => TNewErr): this | Result<T, TNewErr>;
    /**
     * @returns the given Result if this Result is Err, otherwise this.
     */
    or<TOther, TOtherErr, TR extends Result<TOther, TOtherErr>>(res: TR): this | TR;
    /**
     * Calls the given callback with the contained error value if this Result is Err.
     *
     * @returns the Result returned by the given callback, otherwise this Result
     */
    orElse<TOther, TOtherErr, TR extends Result<TOther, TOtherErr>>(op: (error: TErr) => TR): this | TR;
    /**
     * @returns the given Result if this Result is Ok, otherwise this.
     */
    and<TOther, TOtherErr, TR extends Result<TOther, TOtherErr>>(res: TR): this | TR;
    /**
     * Calls the given callback with the contained value if this Result is Ok.
     *
     * @returns the Result returned by the given callback, otherwise this Result
     */
    andThen<TOther, TOtherErr, TR extends Result<TOther, TOtherErr>>(op: (value: T) => TR): this | TR;
    /**
     * @returns the contained value if this Result is Ok.
     * @throws if this Result is Err, with the error message provided by the containing error.
     */
    unwrap(): T;
    /**
     * @returns the contained value if this Result is Ok or the given value otherwise.
     */
    unwrapOr<TDef>(def: TDef): T | TDef;
    /**
     * Calls the given function with the contained error value and returns the value returned by the function if this Result is Err. Otherwise, returns the contained value.
     *
     * @returns The contained value if this Result is Ok or the value returned by the given function otherwise.
     */
    unwrapOrElse<TDef>(op: (error: TErr) => TDef): T | TDef;
    /**
     * Returns the contained value if this Result is Ok, otherwise throws with the given error message.
     *
     * @param message - The error message to be displayed if this Result is Err.
     *
     * @returns The contained value if this Result is Ok.
     * @throws An error with the given error message if this Result is Err.
     *         The error message includes the provided message, as well as the content of the containing error.
     */
    expect(message: string): T;
    /**
     * @returns the contained error value if this Result is Err.
     * @throws the contained value as the error message if this Result is Ok
     */
    unwrapErr(): TErr;
    /**
     * Returns the contained error value if this Result is Err, otherwise throws with the given error message.
     *
     * @param message - The error message to be displayed if this Result is Ok.
     *
     * @returns The contained error value if this Result is Err.
     * @throws An error with the given error message and the content of the containing error as the message if this Result is Ok.
     */
    expectErr(message: string): TErr;
}
/**
 * Stores the result of a successful operation.
 * Access the contained via {@link Ok.value}.
 * Refer to {@link ResultBase} for available methods.
 *
 * @see ResultBase
 */
declare class Ok<T> implements ResultBase<T, never> {
    readonly value: T;
    constructor(value: T);
    isOk(): this is Ok<T>;
    isErr(): this is Err<never>;
    inspect(f: (value: T) => unknown): this;
    inspectErr(f: (error: never) => unknown): this;
    map<TNew>(mapper: (value: T) => TNew): Ok<TNew>;
    mapOr<TNew, TDef>(def: TDef, mapper: (result: T) => TNew): TNew;
    mapOrElse<TNew, TDef>(errMapper: (error: never) => TDef, mapper: (value: T) => TNew): TNew;
    mapErr<TNewErr>(mapper: (error: never) => TNewErr): this;
    or<TOther, TOtherErr, TR extends Result<TOther, TOtherErr>>(other: TR): this;
    orElse<TOther, TOtherErr, TR extends Result<TOther, TOtherErr>>(op: (error: never) => TR): this;
    and<TOther, TOtherErr, TR extends Result<TOther, TOtherErr>>(other: TR): TR;
    andThen<TOther, TOtherErr, TR extends Result<TOther, TOtherErr>>(op: (value: T) => TR): TR;
    unwrap(): T;
    unwrapOr<TDef>(def: TDef): T;
    unwrapOrElse<TDef>(op: (error: never) => TDef): T;
    expect(msg: string): T;
    unwrapErr(): never;
    expectErr(message: string): never;
}
/**
 * Stores the error of a failed operation.
 * Access the error via {@link Err.error}.
 * Refer to {@link ResultBase} for available methods.
 *
 * @see ResultBase
 */
declare class Err<TErr> implements ResultBase<never, TErr> {
    readonly error: TErr;
    constructor(error: TErr);
    isOk(): this is Ok<never>;
    isErr(): this is Err<TErr>;
    inspect(f: (value: never) => unknown): this;
    inspectErr(f: (error: TErr) => unknown): this;
    map<TNew>(mapper: (value: never) => TNew): this;
    mapOr<TNew, TDef>(def: TDef, mapper: (value: never) => TNew): TDef;
    mapOrElse<TNew, TDef>(errMapper: (error: TErr) => TDef, mapper: (value: never) => TNew): TDef;
    mapErr<TNewErr>(mapper: (error: TErr) => TNewErr): Err<TNewErr>;
    or<TOther, TOtherErr, TR extends Result<TOther, TOtherErr>>(other: TR): TR;
    orElse<TOther, TOtherErr, TR extends Result<TOther, TOtherErr>>(op: (error: TErr) => TR): TR;
    and<TOther, TOtherErr, TR extends Result<TOther, TOtherErr>>(other: TR): this;
    andThen<TOther, TOtherErr, TR extends Result<TOther, TOtherErr>>(op: (value: never) => TR): this;
    unwrap(): never;
    unwrapOr<TDef>(def: TDef): TDef;
    unwrapOrElse<TDef>(op: (error: TErr) => TDef): TDef;
    expect(message: string): never;
    unwrapErr(): TErr;
    expectErr(message: string): TErr;
}
/**
 * Represents the result of a fail-able operation.
 * A successful operation returns {@link Ok}, and a failed operation returns {@link Err}.
 *
 * Refer to {@link ResultBase} for methods available on a {@link Result}.
 *
 * @see ResultBase
 */
type Result<T, TErr> = Ok<T> | Err<TErr>;
declare function ok(): Ok<void>;
declare function ok<T>(value: T): Ok<T>;
declare function err(): Err<void>;
declare function err<T>(error: T): Err<T>;
/**
 * Calls the given function, catches any thrown error into an {@link Err},
 * and wraps the returned value with an {@link Ok} if nothing goes wrong.
 */
declare function trys<T>(fn: () => T): Result<T, unknown>;
declare function trys(fn: () => void): Result<void, unknown>;
/**
 * Stores the result of the given {@link Promise} into a {@link Result}.
 * If the promise fails, {@link Err} is returned. If the promise succeeds, {@link Ok} is returned.
 *
 * @example
 * const res = await tryp(fetch("/my/api")).mapErr((err) => apiError(err))
 * if (res.isErr()) {
 *   return err(res.error)
 * }
 */
declare function tryp(promise: Promise<void>): Promise<Result<void, unknown>>;
declare function tryp<T>(promise: Promise<T>): Promise<Result<T, unknown>>;

export { Err, Ok, type Result, type ResultBase, err, ok, tryp, trys };
