From 9418133a3a4771121be7b224c9aaf5ed76287788 Mon Sep 17 00:00:00 2001 From: Rajat Date: Fri, 31 Dec 2021 01:01:24 +0530 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20Merge=20PR=20#57776=20[jest]=20a?= =?UTF-8?q?dding=20definitions=20for=20`mocked`=20function=20by=20@k-rajat?= =?UTF-8?q?19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * mocked * fixing jest-tests * prettier * removing prettier changes * tslint * making requested changes * jest-tests * removing comments --- types/jest/index.d.ts | 49 +++++++++++++++++++++++++++++++++++++++- types/jest/jest-tests.ts | 5 ++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/types/jest/index.d.ts b/types/jest/index.d.ts index bf9f61899643d88..0970a208ac52beb 100644 --- a/types/jest/index.d.ts +++ b/types/jest/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Jest 27.0 +// Type definitions for Jest 27.4 // Project: https://jestjs.io/ // Definitions by: Asana (https://asana.com) // Ivo Stratev @@ -178,6 +178,25 @@ declare namespace jest { * Mocks a module with an auto-mocked version when it is being required. */ function mock(moduleName: string, factory?: () => unknown, options?: MockOptions): typeof jest; + + /** + * The mocked test helper provides typings on your mocked modules and even + * their deep methods, based on the typing of its source. It makes use of + * the latest TypeScript feature, so you even have argument types + * completion in the IDE (as opposed to jest.MockInstance). + * + * Note: while it needs to be a function so that input type is changed, the helper itself does nothing else than returning the given input value. + */ + function mocked(item: T, deep?: false): MaybeMocked; + /** + * The mocked test helper provides typings on your mocked modules and even + * their deep methods, based on the typing of its source. It makes use of + * the latest TypeScript feature, so you even have argument types + * completion in the IDE (as opposed to jest.MockInstance). + * + * Note: while it needs to be a function so that input type is changed, the helper itself does nothing else than returning the given input value. + */ + function mocked(item: T, deep: true): MaybeMockedDeep; /** * Returns the actual module instead of a mock, bypassing all checks on * whether the module should receive a mock implementation or not. @@ -312,6 +331,34 @@ declare namespace jest { virtual?: boolean | undefined; } + type MockableFunction = (...args: any[]) => any; + type MethodKeysOf = { [K in keyof T]: T[K] extends MockableFunction ? K : never }[keyof T]; + type PropertyKeysOf = { [K in keyof T]: T[K] extends MockableFunction ? never : K }[keyof T]; + type ArgumentsOf = T extends (...args: infer A) => any ? A : never; + type ConstructorArgumentsOf = T extends new (...args: infer A) => any ? A : never; + + interface MockWithArgs extends MockInstance, ArgumentsOf> { + new (...args: ConstructorArgumentsOf): T; + (...args: ArgumentsOf): ReturnType; + } + type MaybeMockedConstructor = T extends new (...args: any[]) => infer R + ? MockInstance> + : T; + type MockedFn = MockWithArgs & { [K in keyof T]: T[K] }; + type MockedFunctionDeep = MockWithArgs & MockedObjectDeep; + type MockedObject = MaybeMockedConstructor & { + [K in MethodKeysOf]: T[K] extends MockableFunction ? MockedFn : T[K]; + } & { [K in PropertyKeysOf]: T[K] }; + type MockedObjectDeep = MaybeMockedConstructor & { + [K in MethodKeysOf]: T[K] extends MockableFunction ? MockedFunctionDeep : T[K]; + } & { [K in PropertyKeysOf]: MaybeMockedDeep }; + type MaybeMockedDeep = T extends MockableFunction + ? MockedFunctionDeep + : T extends object // eslint-disable-line @typescript-eslint/ban-types + ? MockedObjectDeep + : T; + // eslint-disable-next-line @typescript-eslint/ban-types + type MaybeMocked = T extends MockableFunction ? MockedFn : T extends object ? MockedObject : T; type EmptyFunction = () => void; type ArgsType = T extends (...args: infer A) => any ? A : never; type ConstructorArgsType = T extends new (...args: infer A) => any ? A : never; diff --git a/types/jest/jest-tests.ts b/types/jest/jest-tests.ts index 4169455e21c95c1..45bdea34269b12f 100644 --- a/types/jest/jest-tests.ts +++ b/types/jest/jest-tests.ts @@ -531,6 +531,11 @@ class SpyableClass { // $ExpectType SpyInstance || SpyInstance jest.spyOn({ SpyableClass }, "SpyableClass"); +// $ExpectType MockedObject<{}> +jest.mocked({}); +// $ExpectError +jest.mocked(); + interface Type1 { a: number; }