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

TypeScript types for the "./matchers" export don't match implementations #554

Closed
jakeboone02 opened this issue Dec 3, 2023 · 3 comments · Fixed by #566
Closed

TypeScript types for the "./matchers" export don't match implementations #554

jakeboone02 opened this issue Dec 3, 2023 · 3 comments · Fixed by #566
Labels

Comments

@jakeboone02
Copy link
Contributor

jakeboone02 commented Dec 3, 2023

  • @testing-library/jest-dom version: 6.1.5
  • node version: N/A - using Bun 1.0.15
  • jest (or vitest) version: N/A - using bun test
  • npm (or yarn) version: N/A - using Bun 1.0.15
  • @testing-library/react version: 14.1.2

Relevant code or config:

This code works in practice, it's just the types that are causing a problem:

import * as matchers from "@testing-library/jest-dom/matchers";
import { expect, mock, test } from "bun:test";

expect.extend(matchers);
//            ^ Argument of type 'TestingLibraryMatchers<any, void> & Record<string, any>' is not assignable to parameter of type 'ExpectExtendMatchers...

What you did:

Tried to extend expect from bun:test with matchers from @testing-library/jest-dom/matchers.

I don't think this is specific to Bun, but they just added support for expect.extend so I thought I'd give it go.

What happened:

The TypeScript definitions for the "./matchers" export don't seem to match the implementations of the actual matchers.

Take toBeChecked, for example. The implementation is here:

export function toBeChecked(element) {

But the type definition doesn't include the element parameter:

toBeChecked(): R

Also, the R generic is specified as void in the export statement, so the return type is effectively missing as well. (Should be something like { pass: boolean; message: () => string; }.)

declare const matchers: matchers.TestingLibraryMatchers<any, void> &
Record<string, any>
export = matchers

Reproduction:

See "Relevant code" section above.

Problem description:

Types should match the implementation.

Suggested solution:

https://github.com/testing-library/jest-dom/blob/main/types/matchers.d.ts should be updated to match the implementation of the matcher functions. If those types are correct in some other context (since they do seem to match the implementation when called as a property of an expect() result), then a separate definition file should be created for the "./matchers" export.

@soullivaneuh
Copy link

I tried the same thing and got the similar problem.

Here is the related test:

import {
  expect,
  test,
} from 'bun:test'
import {
  render,
  screen,
} from '@testing-library/react'
import * as extensions from '@testing-library/jest-dom/matchers'
import App from './App'

expect.extend(extensions)

test('renders', async () => {
  render(<App  />);

  expect(screen.getByText('Click on the Vite and React logos to learn more')).toBeInTheDocument();
})

Running bun tsc --noEmit gave me:

src/App.test.tsx:12:15 - error TS2345: Argument of type 'TestingLibraryMatchers<any, void> & Record<string, any>' is not assignable to parameter of type 'ExpectExtendMatchers<{ [x: string]: ...; toBeInTheDOM: unknown; toBeInTheDocument: unknown; toBeVisible: unknown; toBeEmpty: unknown; toBeEmptyDOMElement: unknown; toBeDisabled: unknown; toBeEnabled: unknown; toBeInvalid: unknown; toBeRequired: unknown; toBeValid: unknown; toContainElement: unknown; ... 15 more ...;...'.
  Types of property 'toBeInTheDOM' are incompatible.
    Type '(container?: HTMLElement | SVGElement | undefined) => void' is not assignable to type 'CustomMatcher<unknown, any[]>'.
      Types of parameters 'container' and 'expected' are incompatible.
        Type 'unknown' is not assignable to type 'HTMLElement | SVGElement | undefined'.

12 expect.extend(extensions)
                 ~~~~~~~~~~

src/App.test.tsx:17:79 - error TS2339: Property 'toBeInTheDocument' does not exist on type 'Matchers<HTMLElement>'.

17   expect(screen.getByText('Click on the Vite and React logos to learn more')).toBeInTheDocument();
                                                                                 ~~~~~~~~~~~~~~~~~

However, the test is running as expected. Only the typing is the issue here.

@jakeboone02
Copy link
Contributor Author

@soullivaneuh I just submitted #566 to address this issue.

Copy link

🎉 This issue has been resolved in version 6.2.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants