jest icon indicating copy to clipboard operation
jest copied to clipboard

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

Open viceice opened this issue 3 years ago • 17 comments

Version

29.0.1

Steps to reproduce

  1. add @types/[email protected] and [email protected] 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

viceice avatar Aug 31 '22 12:08 viceice

PR welcome to align with @types/jest 👍

SimenB avatar Aug 31 '22 13:08 SimenB

https://github.com/facebook/jest/releases/tag/v29.0.3

SimenB avatar Sep 10 '22 14:09 SimenB

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 avatar Sep 10 '22 15:09 SimenB

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.

mrazauskas avatar Sep 10 '22 15:09 mrazauskas

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

We could possibly move our ImportMeta declaration?

SimenB avatar Sep 10 '22 16:09 SimenB

Trying my luck with https://github.com/DefinitelyTyped/DefinitelyTyped/pull/62204

mrazauskas avatar Sep 10 '22 16:09 mrazauskas

There is more https://github.com/DefinitelyTyped/DefinitelyTyped/pull/62206 (got merged 🚀)

mrazauskas avatar Sep 11 '22 05:09 mrazauskas

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

  • https://github.com/renovatebot/renovate/pull/17737

viceice avatar Sep 12 '22 15:09 viceice

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 avatar Sep 12 '22 16:09 mrazauskas

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.

mrazauskas avatar Sep 14 '22 17:09 mrazauskas

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?

SimenB avatar Sep 14 '22 17:09 SimenB

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 avatar Sep 14 '22 18:09 mrazauskas

The missing part is here: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/62259

mrazauskas avatar Sep 14 '22 18:09 mrazauskas

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

SimenB avatar Sep 14 '22 19:09 SimenB

@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

SimenB avatar Sep 15 '22 15:09 SimenB

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 (;

mrazauskas avatar Sep 16 '22 07:09 mrazauskas

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'

LinusU avatar Sep 21 '22 15:09 LinusU

does it work with https://github.com/facebook/jest/releases/tag/v29.1.0?

SimenB avatar Sep 28 '22 07:09 SimenB

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.

mrazauskas avatar Sep 28 '22 08:09 mrazauskas

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

smaye81 avatar Sep 28 '22 13:09 smaye81

Great, thanks!

SimenB avatar Sep 28 '22 13:09 SimenB

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[bot] avatar Oct 30 '22 00:10 github-actions[bot]