Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(jest): add mocked property #57775

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion 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 <https://github.com/NoHomey>
Expand Down Expand Up @@ -73,6 +73,7 @@ type ExtractEachCallbackArgs<T extends ReadonlyArray<any>> = {
];

declare namespace jest {
const mocked: typeof import('jest-mock').mocked;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we adding jest-mock dependency here
should we need to import all types/functions exported by jest-mock like this. No ?
so that it looks consistent :)
or it doesn't matter

Copy link
Contributor Author

@G-Rath G-Rath Dec 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now it doesn't matter as this is a new API whereas the existing types are slightly different from what's provided in jest-mock so need to be checked first and that's not as important as typing the new api.

Copy link
Contributor

@SimenB SimenB Dec 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

won't this break for people who have e.g.

function doSomething(jest.Mock<something, somethingElse>) {
}

doSomething(jest.mocked({}));

?

(Long term I want @types/jest to import all of its things from Jest itself (#44365), but as long as that's not the case, mixing seems less than ideal?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you've provided isn't actually valid because jest.Mock is actually sort of poorly named jest.MockedFunction, where as jest.mocked({}) returns jest.MockedObject.

However no it won't because the types should all be compatible.

here's some code showcasing this
import { mocked as tsJestMocked } from 'ts-jest/utils';
// import { jest } from '@jest/globals';
import * as MockTypes from 'jest-mock';
import * as jestMock from 'jest-mock';

// type MockTypes = jest;
// type MockTypes = typeof jestMock;
const mocked = jestMock.mocked;
// const mocked = jest.mocked;
// const mocked = tsJestMocked;

class Greeter {
  private readonly _greeting: string;

  public constructor(greeting: string) {
    this._greeting = greeting;
  }

  public get greeting() {
    return this._greeting;
  }

  public sayHello(target: string) {
    console.log(`${this._greeting} ${target}`);
  }
}

interface Point {
  x: string;
  y: number;
}

const makePoint = (x: string, y: number): Point => {
  return { x, y };
};

declare function doSomethingWithMockedFn(
  fn: jest.Mock<Point, [string, number]>
): void;
declare function doSomethingWithMockedMakePoint(
  fn: jest.Mocked<typeof makePoint>
): void;

declare function doSomethingWithMockedObject(fn: jest.Mocked<Point>): void;

declare function doSomethingWithMockedClass(
  fn: jest.MockedClass<typeof Greeter>
): void;

doSomethingWithMockedFn(mocked(makePoint));
doSomethingWithMockedMakePoint(mocked(makePoint));
doSomethingWithMockedObject(mocked({ x: '', y: 1 }));
doSomethingWithMockedClass(mocked(Greeter));

Regardless of what combination you use (e.g. types from jest-mocked + mocked from the jest global, everything from jest-mocked, everything from ts-jest, renaming the jest.<type> to be MockTypes.<type>, etc) the errors and passes are the same.

The first and last doSomething method calls have errors because of type issues (which basically boil down to the conditional typing of mocked resulting in a more accurate type than what's being used) while the middle two calls don't.


Long term I want @types/jest to import all of its things from Jest itself (#44365), but as long as that's not the case, mixing seems less than ideal?

That was part of my goal here, as we're already mixing types with jest-diff and pretty-format - but I didn't want to change the existing types in this PR because of the size of that work.

However looking at it with fresh eyes, it'll be a better IDE experience anyway to go with #57776 so let's do that.

https://github.com/DefinitelyTyped/DefinitelyTyped/pull/57776/files#r772003152

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(the problem with #57776 is it is mixing types too, but it's more subtle because they have slightly different names)

/**
* Disables automatic mocking in the module loader.
*/
Expand Down
6 changes: 6 additions & 0 deletions types/jest/jest-tests.ts
Expand Up @@ -1572,3 +1572,9 @@ test(`returns a Promise<any> and takes done`, (done) => {
test(`async function takes done`, async (done) => {
done();
});

// $ExpectError
jest.mocked();

// $ExpectType MockedObject<{}>
jest.mocked({});
1 change: 1 addition & 0 deletions types/jest/package.json
Expand Up @@ -2,6 +2,7 @@
"private": true,
"dependencies": {
"jest-diff": "^27.0.0",
"jest-mock": "^27.4.0",
"pretty-format": "^27.0.0"
},
"exports": {
Expand Down