interface MockResultReturn<T> {
    type: "return";
    /**
     * The value that was returned from the function. If function returned a Promise, then this will be a resolved value.
     */
    value: T;
}
interface MockResultIncomplete {
    type: "incomplete";
    value: undefined;
}
interface MockResultThrow {
    type: "throw";
    /**
     * An error that was thrown during function execution.
     */
    value: any;
}
interface MockSettledResultFulfilled<T> {
    type: "fulfilled";
    value: T;
}
interface MockSettledResultRejected {
    type: "rejected";
    value: any;
}
export type MockResult<T> = MockResultReturn<T> | MockResultThrow | MockResultIncomplete;
export type MockSettledResult<T> = MockSettledResultFulfilled<T> | MockSettledResultRejected;
export interface MockContext<T extends Procedure> {
    /**
     * This is an array containing all arguments for each call. One item of the array is the arguments of that call.
     *
     * @example
     * const fn = vi.fn()
     *
     * fn('arg1', 'arg2')
     * fn('arg3')
     *
     * fn.mock.calls === [
     *   ['arg1', 'arg2'], // first call
     *   ['arg3'], // second call
     * ]
     */
    calls: Parameters<T>[];
    /**
     * This is an array containing all instances that were instantiated when mock was called with a `new` keyword. Note that this is an actual context (`this`) of the function, not a return value.
     */
    instances: ReturnType<T>[];
    /**
     * An array of `this` values that were used during each call to the mock function.
     */
    contexts: ThisParameterType<T>[];
    /**
     * The order of mock's execution. This returns an array of numbers which are shared between all defined mocks.
     *
     * @example
     * const fn1 = vi.fn()
     * const fn2 = vi.fn()
     *
     * fn1()
     * fn2()
     * fn1()
     *
     * fn1.mock.invocationCallOrder === [1, 3]
     * fn2.mock.invocationCallOrder === [2]
     */
    invocationCallOrder: number[];
    /**
     * This is an array containing all values that were `returned` from the function.
     *
     * The `value` property contains the returned value or thrown error. If the function returned a `Promise`, then `result` will always be `'return'` even if the promise was rejected.
     *
     * @example
     * const fn = vi.fn()
     *   .mockReturnValueOnce('result')
     *   .mockImplementationOnce(() => { throw new Error('thrown error') })
     *
     * const result = fn()
     *
     * try {
     *   fn()
     * }
     * catch {}
     *
     * fn.mock.results === [
     *   {
     *     type: 'return',
     *     value: 'result',
     *   },
     *   {
     *     type: 'throw',
     *     value: Error,
     *   },
     * ]
     */
    results: MockResult<ReturnType<T>>[];
    /**
     * An array containing all values that were `resolved` or `rejected` from the function.
     *
     * This array will be empty if the function was never resolved or rejected.
     *
     * @example
     * const fn = vi.fn().mockResolvedValueOnce('result')
     *
     * const result = fn()
     *
     * fn.mock.settledResults === []
     * fn.mock.results === [
     *   {
     *     type: 'return',
     *     value: Promise<'result'>,
     *   },
     * ]
     *
     * await result
     *
     * fn.mock.settledResults === [
     *   {
     *     type: 'fulfilled',
     *     value: 'result',
     *   },
     * ]
     */
    settledResults: MockSettledResult<Awaited<ReturnType<T>>>[];
    /**
     * This contains the arguments of the last call. If spy wasn't called, will return `undefined`.
     */
    lastCall: Parameters<T> | undefined;
}
type Procedure = (...args: any[]) => any;
type NormalizedPrecedure<T extends Procedure> = (...args: Parameters<T>) => ReturnType<T>;
type Methods<T> = keyof {
    [K in keyof T as T[K] extends Procedure ? K : never]: T[K];
};
type Properties<T> = {
    [K in keyof T]: T[K] extends Procedure ? never : K;
}[keyof T] & (string | symbol);
type Classes<T> = {
    [K in keyof T]: T[K] extends new (...args: any[]) => any ? K : never;
}[keyof T] & (string | symbol);
export interface MockInstance<T extends Procedure = Procedure> {
    /**
     * Use it to return the name given to mock with method `.mockName(name)`.
     */
    getMockName(): string;
    /**
     * Sets internal mock name. Useful to see the name of the mock if an assertion fails.
     */
    mockName(n: string): this;
    /**
     * Current context of the mock. It stores information about all invocation calls, instances, and results.
     */
    mock: MockContext<T>;
    /**
     * Clears all information about every call. After calling it, all properties on `.mock` will return an empty state. This method does not reset implementations.
     *
     * It is useful if you need to clean up mock between different assertions.
     */
    mockClear(): this;
    /**
     * Does what `mockClear` does and makes inner implementation an empty function (returning `undefined` when invoked). This also resets all "once" implementations.
     *
     * This is useful when you want to completely reset a mock to the default state.
     */
    mockReset(): this;
    /**
     * Does what `mockReset` does and restores inner implementation to the original function.
     *
     * Note that restoring mock from `vi.fn()` will set implementation to an empty function that returns `undefined`. Restoring a `vi.fn(impl)` will restore implementation to `impl`.
     */
    mockRestore(): void;
    /**
     * Returns current mock implementation if there is one.
     *
     * If mock was created with `vi.fn`, it will consider passed down method as a mock implementation.
     *
     * If mock was created with `vi.spyOn`, it will return `undefined` unless a custom implementation was provided.
     */
    getMockImplementation(): NormalizedPrecedure<T> | undefined;
    /**
     * Accepts a function that will be used as an implementation of the mock.
     * @example
     * const increment = vi.fn().mockImplementation(count => count + 1);
     * expect(increment(3)).toBe(4);
     */
    mockImplementation(fn: NormalizedPrecedure<T>): this;
    /**
     * Accepts a function that will be used as a mock implementation during the next call. Can be chained so that multiple function calls produce different results.
     * @example
     * const fn = vi.fn(count => count).mockImplementationOnce(count => count + 1);
     * expect(fn(3)).toBe(4);
     * expect(fn(3)).toBe(3);
     */
    mockImplementationOnce(fn: NormalizedPrecedure<T>): this;
    /**
     * Overrides the original mock implementation temporarily while the callback is being executed.
     * @example
     * const myMockFn = vi.fn(() => 'original')
     *
     * myMockFn.withImplementation(() => 'temp', () => {
     *   myMockFn() // 'temp'
     * })
     *
     * myMockFn() // 'original'
     */
    withImplementation<T2>(fn: NormalizedPrecedure<T>, cb: () => T2): T2 extends Promise<unknown> ? Promise<this> : this;
    /**
     * Use this if you need to return `this` context from the method without invoking actual implementation.
     */
    mockReturnThis(): this;
    /**
     * Accepts a value that will be returned whenever the mock function is called.
     */
    mockReturnValue(obj: ReturnType<T>): this;
    /**
     * Accepts a value that will be returned during the next function call. If chained, every consecutive call will return the specified value.
     *
     * When there are no more `mockReturnValueOnce` values to use, mock will fallback to the previously defined implementation if there is one.
     * @example
     * const myMockFn = vi
     *   .fn()
     *   .mockReturnValue('default')
     *   .mockReturnValueOnce('first call')
     *   .mockReturnValueOnce('second call')
     *
     * // 'first call', 'second call', 'default'
     * console.log(myMockFn(), myMockFn(), myMockFn())
     */
    mockReturnValueOnce(obj: ReturnType<T>): this;
    /**
     * Accepts a value that will be resolved when async function is called.
     * @example
     * const asyncMock = vi.fn().mockResolvedValue(42)
     * asyncMock() // Promise<42>
     */
    mockResolvedValue(obj: Awaited<ReturnType<T>>): this;
    /**
     * Accepts a value that will be resolved during the next function call. If chained, every consecutive call will resolve specified value.
     * @example
     * const myMockFn = vi
     *   .fn()
     *   .mockResolvedValue('default')
     *   .mockResolvedValueOnce('first call')
     *   .mockResolvedValueOnce('second call')
     *
     * // Promise<'first call'>, Promise<'second call'>, Promise<'default'>
     * console.log(myMockFn(), myMockFn(), myMockFn())
     */
    mockResolvedValueOnce(obj: Awaited<ReturnType<T>>): this;
    /**
     * Accepts an error that will be rejected when async function is called.
     * @example
     * const asyncMock = vi.fn().mockRejectedValue(new Error('Async error'))
     * await asyncMock() // throws 'Async error'
     */
    mockRejectedValue(obj: any): this;
    /**
     * Accepts a value that will be rejected during the next function call. If chained, every consecutive call will reject specified value.
     * @example
     * const asyncMock = vi
     *   .fn()
     *   .mockResolvedValueOnce('first call')
     *   .mockRejectedValueOnce(new Error('Async error'))
     *
     * await asyncMock() // first call
     * await asyncMock() // throws "Async error"
     */
    mockRejectedValueOnce(obj: any): this;
}
export interface Mock<T extends Procedure = Procedure> extends MockInstance<T> {
    new (...args: Parameters<T>): ReturnType<T>;
    (...args: Parameters<T>): ReturnType<T>;
}
type PartialMaybePromise<T> = T extends Promise<Awaited<T>> ? Promise<Partial<Awaited<T>>> : Partial<T>;
export interface PartialMock<T extends Procedure = Procedure> extends MockInstance<(...args: Parameters<T>) => PartialMaybePromise<ReturnType<T>>> {
    new (...args: Parameters<T>): ReturnType<T>;
    (...args: Parameters<T>): ReturnType<T>;
}
export type MaybeMockedConstructor<T> = T extends new (...args: Array<any>) => infer R ? Mock<(...args: ConstructorParameters<T>) => R> : T;
export type MockedFunction<T extends Procedure> = Mock<T> & {
    [K in keyof T]: T[K];
};
export type PartiallyMockedFunction<T extends Procedure> = PartialMock<T> & {
    [K in keyof T]: T[K];
};
export type MockedFunctionDeep<T extends Procedure> = Mock<T> & MockedObjectDeep<T>;
export type PartiallyMockedFunctionDeep<T extends Procedure> = PartialMock<T> & MockedObjectDeep<T>;
export type MockedObject<T> = MaybeMockedConstructor<T> & {
    [K in Methods<T>]: T[K] extends Procedure ? MockedFunction<T[K]> : T[K];
} & {
    [K in Properties<T>]: T[K];
};
export type MockedObjectDeep<T> = MaybeMockedConstructor<T> & {
    [K in Methods<T>]: T[K] extends Procedure ? MockedFunctionDeep<T[K]> : T[K];
} & {
    [K in Properties<T>]: MaybeMockedDeep<T[K]>;
};
export type MaybeMockedDeep<T> = T extends Procedure ? MockedFunctionDeep<T> : T extends object ? MockedObjectDeep<T> : T;
export type MaybePartiallyMockedDeep<T> = T extends Procedure ? PartiallyMockedFunctionDeep<T> : T extends object ? MockedObjectDeep<T> : T;
export type MaybeMocked<T> = T extends Procedure ? MockedFunction<T> : T extends object ? MockedObject<T> : T;
export type MaybePartiallyMocked<T> = T extends Procedure ? PartiallyMockedFunction<T> : T extends object ? MockedObject<T> : T;
interface Constructable {
    new (...args: any[]): any;
}
export type MockedClass<T extends Constructable> = MockInstance<(...args: ConstructorParameters<T>) => InstanceType<T>> & {
    prototype: T extends {
        prototype: any;
    } ? Mocked<T["prototype"]> : never;
} & T;
export type Mocked<T> = {
    [P in keyof T]: T[P] extends Procedure ? MockInstance<T[P]> : T[P] extends Constructable ? MockedClass<T[P]> : T[P];
} & T;
export declare const mocks: Set<MockInstance>;
export declare function isMockFunction(fn: any): fn is MockInstance;
export declare function spyOn<T, S extends Properties<Required<T>>>(obj: T, methodName: S, accessType: "get"): MockInstance<() => T[S]>;
export declare function spyOn<T, G extends Properties<Required<T>>>(obj: T, methodName: G, accessType: "set"): MockInstance<(arg: T[G]) => void>;
export declare function spyOn<T, M extends Classes<Required<T>> | Methods<Required<T>>>(obj: T, methodName: M): Required<T>[M] extends {
    new (...args: infer A): infer R;
} ? MockInstance<(this: R, ...args: A) => R> : T[M] extends Procedure ? MockInstance<T[M]> : never;
export declare function fn<T extends Procedure = Procedure>(implementation?: T): Mock<T>;
export declare const mockAny: <T>(obj: T) => T;
export {};
