Skip to content

Instantly share code, notes, and snippets.

@G-Rath
Created March 26, 2019 23:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save G-Rath/66246c74ee69d952fde71a1bc3f8687d to your computer and use it in GitHub Desktop.
Save G-Rath/66246c74ee69d952fde71a1bc3f8687d to your computer and use it in GitHub Desktop.
/// <reference types="jest" />
import { mocked as mockedCore } from 'ts-jest';
declare type MockableFunction = (...args: any[]) => any
declare type MethodKeysOf<T> = { [K in keyof T]: T[K] extends MockableFunction ? K : never }[keyof T]
declare type PropertyKeysOf<T> = { [K in keyof T]: T[K] extends MockableFunction ? never : K }[keyof T]
declare type ArgumentsOf<T> = T extends (...args: infer A) => any ? A : never
declare type ConstructorArgumentsOf<T> = T extends new (...args: infer A) => any ? A : never
interface MockWithArgs<T extends MockableFunction> extends jest.MockInstance<ReturnType<T>, ArgumentsOf<T>> {
new(...args: ConstructorArgumentsOf<T>): T
(...args: ArgumentsOf<T>): ReturnType<T>
}
declare type MaybeMockedConstructor<T> = T extends new (...args: any[]) => infer R
? jest.MockInstance<R, ConstructorArgumentsOf<T>>
: {}
declare type MockedFunction<T extends MockableFunction> = MockWithArgs<T> & { [K in keyof T]: T[K] }
declare type MockedFunctionDeep<T extends MockableFunction> = MockWithArgs<T> & MockedObjectDeep<T>
declare type MockedObject<T> = MaybeMockedConstructor<T> &
{ [K in MethodKeysOf<T>]: T[K] extends MockableFunction ? MockedFunction<T[K]> : T[K] } &
{ [K in PropertyKeysOf<T>]: T[K] }
declare type MockedObjectDeep<T> = MaybeMockedConstructor<T> &
{ [K in MethodKeysOf<T>]: T[K] extends MockableFunction ? MockedFunctionDeep<T[K]> : T[K] } &
{ [K in PropertyKeysOf<T>]: MaybeMockedDeep<T[K]> }
export declare type MaybeMockedDeep<T> = T extends MockableFunction
? MockedFunctionDeep<T>
: T extends object
? MockedObjectDeep<T>
: T
export declare type MaybeMocked<T> = T extends MockableFunction ? MockedFunction<T> : T extends object ? MockedObject<T> : T
export function mocked<T>(item: T, deep?: false): MaybeMocked<T>
export function mocked<T>(item: T, deep: true): MaybeMockedDeep<T>
export function mocked<T>(item: T, _deep?: false): MaybeMocked<T> | MaybeMockedDeep<T>;
export function mocked<T>(item: T, deep?: true | false): MaybeMocked<T> | MaybeMockedDeep<T> {
return mockedCore(item, deep as false | undefined) as any;
}
export {};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment