type AnyFunction = (...args: any[]) => any; type Tail = T extends [any, ...infer R] ? R : []; type OverloadedParameters = T extends { (...args: infer A): any; (...args: infer B): any; } ? A | B : T extends (...args: infer A) => any ? A : never; type OverloadedReturnType = T extends { (...args: any[]): infer A; (...args: any[]): infer B; } ? A | B : T extends (...args: any[]) => infer A ? A : never; type OptionalTuple = { [K in keyof T]?: T[K] }; type UnwrapPromise = T extends Promise ? U : T; type CallbackFor = TArgs extends any[] ? (...args: TArgs) => void : never; type FunctionProps = T extends (...args: any[]) => any ? { [K in Exclude]: Mocked } : {}; type MockedFunction = MockFunction< OverloadedParameters, OverloadedReturnType > & T & FunctionProps; interface RepeatControl { repeat(times: number): RepeatControl; repeatAny(): RepeatControl; } interface ExpectationTerminal { return(value: R): RepeatControl; returnLoose(value?: any): RepeatControl; whenCalled(callback: CallbackFor): ExpectationTerminal; repeat(times: number): RepeatControl; repeatAny(): RepeatControl; throw(error: any): ExpectationTerminal; resolve(value: UnwrapPromise): RepeatControl; resolveLoose(value?: any): RepeatControl; reject(error: Error): RepeatControl; } interface ExpectationChain extends ExpectationTerminal { expect(arg?: TArgs[0]): ExpectationChain, R, TOrigArgs>; /** @deprecated Use ignoreAll() instead. */ expectAnything(): ExpectationChain; ignoreAll(): ExpectationChain; expectLoose(...args: any[]): ExpectationChain; ignore(): ExpectationChain, R, TOrigArgs>; /** @deprecated Use expect() instead. */ expectArray( value?: TArgs[0] extends any[] ? TArgs[0] : any[] ): ExpectationChain, R, TOrigArgs>; } interface MockFunction { (...args: TArgs): R; // Allow any-args calls in addition to the original signature. (...args: any[]): any; expect(...args: OptionalTuple): ExpectationChain, R, TArgs>; ignore(): ExpectationChain, R, TArgs>; /** @deprecated Use expect() instead. */ expectArray( value?: TArgs[0] extends any[] ? TArgs[0] : any[] ): ExpectationChain, R, TArgs>; /** @deprecated Use ignoreAll() instead. */ expectAnything(): ExpectationChain; ignoreAll(): ExpectationChain; // Explicit loose expectations. expectLoose(...args: any[]): ExpectationChain; verify(): true; reset(): void; } type Mocked = T extends AnyFunction ? MockedFunction : T extends object ? { [K in keyof T]: Mocked } & { verify: () => true } : T; interface RequireExpectation { return(value: any): RequireExpectation; repeat(times: number): RequireExpectation; repeatAny(): RequireExpectation; whenCalled(callback: (...args: any[]) => void): RequireExpectation; } interface ThenableMock { (valueToResolveWith?: T | null, errorToFailWith?: any): ThenableMock; then( success?: (value: T) => U | ThenableMock | PromiseLike, fail?: (error: any) => U | ThenableMock | PromiseLike ): ThenableMock; resolve(value?: T): ThenableMock; reject(error: any): ThenableMock; } declare function mock(): T extends any[] ? MockFunction : Mocked; declare function mock( original: T ): MockedFunction; declare function mock(subject: T): Mocked; declare function expectRequire(moduleName: string): RequireExpectation; declare namespace expectRequire { function reset(): void; } declare function requireMock( moduleName: string ): MockFunction; declare namespace requireMock { function reset(): void; } declare function promise(): ThenableMock; declare const aMock: { mock: typeof mock; expectRequire: typeof expectRequire; requireMock: typeof requireMock; promise: typeof promise; }; export = aMock;