jest-native: Property 'toHaveTextContent' does not exist on type 'Matchers & ...' (and any other matcher from library)

  • react-native or expo: expo
  • @testing-library/react-native version: 11.5.0
  • jest-preset: jest-expo
  • react-native version: 0.70.5
  • node version: v16.17.1
  • @testing-library/jest-native version: 5.3.3
  • jest version: 29.3.0

Relevant code or config:

expect(await screen.findByRole('alert')).toHaveTextContent(
  'Incorrect username or password'
);

What you did:

Just using any matcher from jest-native.

What happened:

Typescript complains for missed types. For example, for toHaveTextContent matcher:

Property 'toHaveTextContent' does not exist on type 'Matchers<void> & SnapshotMatchers<void, ReactTestInstance> &
Inverse<JestMatchers<void, ReactTestInstance>> & PromiseMatchers<ReactTestInstance>'.ts(2339)

image

Reproduction:

https://github.com/alexamy/react-native-testing-library-missing-matchers or the same code in zip archive: react-native-testing-library-missing-matchers-45392ed44fe4fa3de64723609f6a0f74227188a4.zip

Problem description:

There is no way to use custom matchers in typescript tests for obvious reason. This problem can be ‘avoided’ by skipping matcher typecheck with @ts-ignore or optionally skipping test typecheck altogether, but it is not really a solution.

Suggested solution:

Modify types in @testing-library/jest-native/extend-expect.d.ts to proper extend the matchers interface.

Btw, there is also import problem on line 3.

image

Matchers interface from Jest: image

I’ve tried to make declare global in project with extended jest’ Matchers interface, but it seems that something is missed, I didn’t get any working result from my tries, this interface seems to be unchanged.

Can you help us fix this issue by submitting a pull request?

I can make a Pull Request with solution for this problem if someone can point me how to properly modify definition file.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 15 (8 by maintainers)

Most upvoted comments

Following this comment (thanks @yordis), this may lead to the solution:

declare module '@jest/expect' {
  interface Matchers<R extends void | Promise<void>> {
    toBeDisabled(): R;
    toBeEmptyElement(): R;
    toBeEnabled(): R;
    toBeVisible(): R;
    toContainElement(element: ReactTestInstance | null): R;
    toHaveTextContent(text: string | RegExp, options?: { normalizeWhitespace: boolean }): R;
    toHaveProp(attr: string, value?: unknown): R;
    toHaveStyle(style: StyleProp<ViewStyle | TextStyle | ImageStyle>): R;
    toHaveAccessibilityState(state: AccessibilityState): R;
    toHaveAccessibilityValue(state: AccessibilityValueMatcher): R;

    /** @deprecated This function has been renamed to `toBeEmptyElement`. */
    toBeEmpty(): R;
  }
}

But it seems that this solution redefines already existing matchers from ‘jest’: image

Made a new branch in repro repo with additional definition file: https://github.com/alexamy/react-native-testing-library-missing-matchers/blob/fix-jest-native-typings/__tests__/globals.d.ts

So, the solution to the missing type definitions for matchers is to use @types/jest and dont use jest explicit globals import from @jest/globals at all.

Similar issue in jest-dom: https://github.com/testing-library/jest-dom/issues/426

Anyone feel free to investigate further, but for now I close this issue.

Maybe we could have a look at some other 3rd party Jest marchers package written in TS and see how they are solving the issue.