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

[Bug]: Interface 'JestImportMeta' incorrectly extends interface 'ImportMeta' #13199

Closed
viceice opened this issue Aug 31, 2022 · 22 comments · Fixed by #13202
Closed

[Bug]: Interface 'JestImportMeta' incorrectly extends interface 'ImportMeta' #13199

viceice opened this issue Aug 31, 2022 · 22 comments · Fixed by #13202

Comments

@viceice
Copy link

viceice commented Aug 31, 2022

Version

29.0.1

Steps to reproduce

  1. add @types/jest@29.0.0 and jest@29.0.1 to a typescript project
  2. Add jest.createMockFromModule call
  3. see compiler error

Expected behavior

Don't see any error.

Actual behavior

$ tsc --noEmit
node_modules/@jest/environment/build/index.d.ts:329:26 - error TS2430: Interface 'JestImportMeta' incorrectly extends interface 'ImportMeta'.
  The types returned by 'jest.createMockFromModule(...)' are incompatible between these types.
    Type 'unknown' is not assignable to type 'T'.
      'T' could be instantiated with an arbitrary type which could be unrelated to 'unknown'.

329 export declare interface JestImportMeta extends ImportMeta {
                             ~~~~~~~~~~~~~~


Found 1 error in node_modules/@jest/environment/build/index.d.ts:329

Additional context

@types/jest declares as function createMockFromModule<T>(moduleName: string): T;
while @jest/environment declares as createMockFromModule(moduleName: string): unknown;

Environment

System:
    OS: Linux 5.10 Ubuntu 20.04.4 LTS (Focal Fossa)
    CPU: (32) x64 AMD Ryzen 9 5950X 16-Core Processor
  Binaries:
    Node: 16.16.0 - /usr/bin/node
    Yarn: 1.22.19 - /usr/bin/yarn
    npm: 8.17.0 - ~/src/renovate/node_modules/.bin/npm
  npmPackages:
    jest: 29.0.1 => 29.0.1
@SimenB
Copy link
Member

SimenB commented Aug 31, 2022

PR welcome to align with @types/jest 👍

@SimenB
Copy link
Member

SimenB commented Sep 10, 2022

@SimenB
Copy link
Member

SimenB commented Sep 10, 2022

Hmm, still an issue @mrazauskas

node_modules/@jest/environment/build/index.d.ts:330:26 - error TS2430: Interface 'JestImportMeta' incorrectly extends interface 'ImportMeta'.
  The types returned by 'jest.clearAllTimers()' are incompatible between these types.
    Type 'void' is not assignable to type 'typeof jest'.

330 export declare interface JestImportMeta extends ImportMeta {
                             ~~~~~~~~~~~~~~


Found 1 error in node_modules/@jest/environment/build/index.d.ts:330

@SimenB SimenB reopened this Sep 10, 2022
@mrazauskas
Copy link
Contributor

Hm.. Seems like this is just another issue with @types/jest. TS complains about the type of jest.clearAllTimers() which is:

https://github.com/facebook/jest/blob/05cd93bc0bfdd91e2e0b42e51b569ba9f073801f/packages/jest-fake-timers/src/legacyFakeTimers.ts#L119

And here:

https://github.com/facebook/jest/blob/05cd93bc0bfdd91e2e0b42e51b569ba9f073801f/packages/jest-environment/src/index.ts#L87

But in @types/jest the return type is typeof jest.

@SimenB
Copy link
Member

SimenB commented Sep 10, 2022

I guess there's not much we can do here?

We could possibly move our ImportMeta declaration?

@mrazauskas
Copy link
Contributor

Trying my luck with DefinitelyTyped/DefinitelyTyped#62204

@mrazauskas
Copy link
Contributor

mrazauskas commented Sep 11, 2022

There is more DefinitelyTyped/DefinitelyTyped#62206 (got merged 🚀)

@viceice
Copy link
Author

viceice commented Sep 12, 2022

I was able to remove the @types/jest dependency. I added some quirks to get everything working again.

@mrazauskas
Copy link
Contributor

Thanks! I looked though quickly lots of interesting and useful details. For instance, it would be nice if jest.requireActual<T>() would take a type arg. In my todo list, will come back to it soon.

@mrazauskas
Copy link
Contributor

We could possibly move our ImportMeta declaration?

@SimenB What did you had in mind here? Just to remove it?

I just checked if @types/jest has definition for unstable_mockModule, but this is missing. Don’t know why. Perhaps, because this API is obviously experimental. Would it make sense to remove types import.meta.jest from @types/jest as well? Same reason. And the problem is solved.

That’s radical idea, I understand. Could work as a compromise for now.

@SimenB
Copy link
Member

SimenB commented Sep 14, 2022

Nah, it should definitely be there, but it's annoying when the types clash. So I meant to move our own to a place it doesn't clash with the @types/jest definition.

On our side, maybe we can do

export interface JestImportMeta extends Omit<ImportMeta, 'jest'> {
  jest: Jest;
}

or something?

@mrazauskas
Copy link
Contributor

Wait. I just checked again and it looks like after requireActual and requireMock got improved on Jest side there is just one change missing @types/jest to make it all work. Let’s try this way first.

@mrazauskas
Copy link
Contributor

The missing part is here: DefinitelyTyped/DefinitelyTyped#62259

@SimenB
Copy link
Member

SimenB commented Sep 14, 2022

Ah nice! Would be awesome to align - makes it easier to make their types based on ours in the future 👍

@SimenB
Copy link
Member

SimenB commented Sep 15, 2022

@mrazauskas after that's released, can we add a type test here that we're compatible?

import {jest as realJest} from '@jest/globals';

expectAssignable<typeof jest>(realJest);

or something like that?

Of course that will yell at us if we become stricter in the future, but I'd rather know and deal with that as the issues crop up

@mrazauskas
Copy link
Contributor

All fixes of @types/jest are merged and shipped with v29.0.3.

Try it out. As mentioned before the culprit now are Jest’s build-in types of requireActual and requireMock. These got fixed in #13253, but are not yet released. The rest seems to be working.

No need to rush at all. Just leaving a note on progress (;

@LinusU
Copy link
Contributor

LinusU commented Sep 21, 2022

I'm getting this error with latest jest (29.0.3) and latest @types/jest (29.0.3):

node_modules/@jest/environment/build/index.d.ts:330:26 - error TS2430: Interface 'JestImportMeta' incorrectly extends interface 'ImportMeta'.
  The types returned by 'jest.requireActual(...)' are incompatible between these types.
    Type 'unknown' is not assignable to type 'TModule'.
      'TModule' could be instantiated with an arbitrary type which could be unrelated to 'unknown'.

330 export declare interface JestImportMeta extends ImportMeta {
                             ~~~~~~~~~~~~~~


Found 1 error in node_modules/@jest/environment/build/index.d.ts:330

I fixed this by removing @types/jest, and adding imports of the globals to every test file, some variation of:

import { afterEach, beforeEach, expect, test } from '@jest/globals'

@SimenB
Copy link
Member

SimenB commented Sep 28, 2022

@mrazauskas
Copy link
Contributor

mrazauskas commented Sep 28, 2022

I was playing with my reproduction. Error is gone with jest v29.1.0 and @types/jest v29.0.3. Would be nice is someone could double check.

@smaye81
Copy link

smaye81 commented Sep 28, 2022

I can confirm this works for me also with jest v29.1.0 and @types/jest v29.0.3. Thanks for the fix!

@SimenB
Copy link
Member

SimenB commented Sep 28, 2022

Great, thanks!

@SimenB SimenB closed this as completed Sep 28, 2022
@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.