jest-dom: Missing type definitions for expect imported from @jest/globals

  • @testing-library/jest-dom version: 5.16.1
  • node version: v16.13.1
  • yarn version: 1.22.17

Relevant code or config:

import { expect } from '@jest/globals';
import '@testing-library/jest-dom';
expect(container).toHaveAttribute('hidden');

What you did:

I imported jest globals from ‘@jest/globals

What happened:

I got the TypeScript error message: TS2339: Property 'toHaveAttribute' does not exist on type 'Matchers '.

Reproduction:

import { expect } from '@jest/globals';
import '@testing-library/jest-dom';
expect(container).toHaveAttribute('hidden');

Problem description:

The custom matchers provided by jest-dom cannot be used in TypeScript if the expect is imported from @jest/globals. Only the global expect is modified, apparently.

Suggested solution:

Extend the interface of expect in the @jest/globals as well.

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 19
  • Comments: 21 (3 by maintainers)

Most upvoted comments

I added the following to my globals.d.ts file


import type { TestingLibraryMatchers } from '@types/testing-library__jest-dom/matchers';

declare module '@jest/expect' {
  export interface Matchers<R = void, T = {}> extends TestingLibraryMatchers<typeof expect.stringContaining, R> {}
}

@jest/globals exports from @jest/expect the expect function

import type { JestExpect } from '@jest/expect';
export declare const expect: JestExpect;

I wasn’t able to solve it the proper way either, but I’ve made a patch on the types coming from @jest/globals, in a declarations.d.ts file at the root of my project I’ve added the following configuration:

import type { TestingLibraryMatchers } from '@types/testing-library__jest-dom/matchers';
// import type { expect } from '@jest/globals'; <-- this was necessary because of my specific setup of cypress + jest, otherwise it was inferring the wrong expect

declare module '@jest/globals/node_modules/expect/build/types' {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/ban-types
  export interface Matchers<R = void, T = {}>
    extends TestingLibraryMatchers<typeof expect.stringContaining, R> {}
}

this feels a bit risky because it relies on a path that could change at any moment (@jest/globals/node_modules/expect/build/types), but it was the best solution I could find for now.

@Vinnl This issue occurs specifically when utilizing the tsc (TypeScript compiler) to generate a compiled distribution bundle. Code is not public,Will try manually in my local

I submitted a PR to DefinitelyTyped that I think should fix this issue: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/65981

After a deeper look, I see that the types of jest-dom extend jest.Matchers

Meanwhile, the types of @jest/globals simply re-export the type of the expect package

I’d naively expect that it’s rather expect.Matchers that should be extended, but after some poking around, I feel that I am out of my depth here.

@abhi-works Is your code public somewhere that I could try it out? Or alternatively, could you open node_modules/@types/testing-library__jest-dom/index.d.ts and apply these changes (i.e. replace the first {} by unknown on line 21) manually, and report back whether that fixes the issue for you?

@Vinnl This issue occurs specifically when utilizing the tsc (TypeScript compiler) to generate a compiled distribution bundle. Code is not public,Will try manually in my local

@Vinnl @gnapse https://github.com/DefinitelyTyped/DefinitelyTyped/pull/65991/files Works locally

@abhi-works Is your code public somewhere that I could try it out? Or alternatively, could you open node_modules/@types/testing-library__jest-dom/index.d.ts and apply these changes (i.e. replace the first {} by unknown on line 21) manually, and report back whether that fixes the issue for you?

Wow, thanks @Vinnl I hit this problem yesterday and your fix has got rid of my issue 😃

In my case, I’ve just switched to expect that comes from jest, not from jest/globals and it works like a charm.