type ErrorObject = {
    stack?: string;
    message?: string;
    status?: number;
};
export type OutcomeJSON<D> = {
    success: true;
    data: D;
} | {
    success: false;
    error: ErrorObject;
};
type OutcomeRunner = (() => any) | Promise<any>;
type Pair<T> = [T, undefined] | [undefined, Error];
type OutcomeReturn<T> = T extends () => Promise<infer X> ? Promise<Outcome<X>> : T extends () => infer X ? Outcome<X> : T extends Promise<infer X> ? Promise<Outcome<X>> : Outcome<T>;
type OutcomeResult<T> = T extends () => Promise<any> ? Promise<boolean> : T extends () => any ? boolean : T extends Promise<any> ? Promise<boolean> : boolean;
export declare function outcome<Run extends OutcomeRunner>(run: Run): OutcomeReturn<Run>;
export declare namespace outcome {
    function succeeds<Run extends OutcomeRunner>(run: OutcomeRunner): OutcomeResult<Run>;
    function fails<Run extends OutcomeRunner>(run: OutcomeRunner): OutcomeResult<Run>;
}
export type Outcome<T = void> = Outcome.OutcomeImpl<T> & Pair<T>;
export declare namespace Outcome {
    export function fromJSON<T>(json: OutcomeJSON<T>): Outcome<T>;
    export function unpack<T>(outcome: Outcome<T>): T;
    export function isOutcome(value: any): value is Outcome;
    export function Success<T>(data: T): Outcome<T>;
    export function Failure<T = any>(error: Error | any): Outcome<T>;
    export abstract class OutcomeImpl<T> {
        success: boolean;
        abstract status: number;
        constructor(success: boolean);
        isSuccess(): this is SuccessOutcome<T>;
        isFailure(): this is FailureOutcome<T>;
        abstract map<U>(fn: (data: T) => U): Outcome<U>;
        abstract toJSON(): OutcomeJSON<T>;
    }
    class SuccessOutcome<T> extends OutcomeImpl<T> {
        value: T;
        status: number;
        error: undefined;
        constructor(value: T);
        [Symbol.iterator](): Generator<T | undefined, void, unknown>;
        map<U>(fn: (data: T) => U): Outcome<U>;
        toJSON(): OutcomeJSON<T>;
    }
    class FailureOutcome<T> extends OutcomeImpl<T> {
        error: Error;
        status: number;
        value: undefined;
        constructor(error: Error);
        [Symbol.iterator](): Generator<Error | undefined, void, unknown>;
        map<U>(fn: (data: T) => U): Outcome<U>;
        toJSON(): OutcomeJSON<T>;
    }
    export {};
}
export {};
