If we follow the path we took in React Testing Library then that'll mean that people wont have to do anything fancy to make the typings/autocomplete show up which would be rad.
Specifically:
testing-library__jest-dom to DefinitelyTyped@types/testing-library__jest-dom to @testing-library/jest-dom dependenciesI just tested it locally and that appears to work. If I have it in my node_modules then it just works™️
Anyone up for this?
Wouldn't this make it possible that the type definitions lag behind the latest features in the library? I understand that part of the motivation in doing this in RTL and DTL was this:
There are no core teammembers with the TS knowledge needed to maintain the types, and they are not well tested or integrated with the codebase.
I'm no expert in TS, but I feel qualified enough to maintain the small needs of jest-dom (which are simpler than the TS needs of RTL/DTL). It's mainly about making sure that PRs that introduce new features or change the external interface make the appropriate updates.
I'll also check if #45 is indeed still an issue. If that's so, then I'd understand the need for this more. Will post my findings here.
My main gripe with DefinitelyTyped is that the type definitions are usually lagging behind and users are unable to use new features until the type definitions get up to speed with the latest developments in the repo.
Also, last time I checked DefinitelyTyped was this huge repo with all the type definitions of everything under the sun, all in the same place. It's hard to search for existing issues of specific libraries, since it's all under the same list of issues. I appreciate its existence because most libs don't provide typings, understandably, but I always thought (and my experience as a consumer of libraries has confirmed) that if the library itself provides the type definitions (e.g. Formik) the experience is so much better. I've been off using TS actively for a few months now, so not sure if any of the reasons for these perceptions have changed. I'd love to know others' input on all this, and if any of this was taken into consideration when making the decision to go in this direction in RTL/DTL.
DefinitelyTyped does have a slight advantage when it comes to global typings, since they will be implicitly included for normal TS projects (those that don’t specify a types tsconfig option).
But as a code/typings contributor to a number of projects, I have to agree with @gnapse about the downsides of projects with typings on DT. With the exception of very popular projects like React, the type definitions are often slightly out of date with the actual library and keeping them in sync involves more overhead than projects with typings in the repo (and more still than projects written in TypeScript).
That said, the DT review/merge process is highly automated and their notification bots are very good, so it’s quite streamlined if you are willing to put in the effort of cloning a second (giant) repo and following the instructions.
If the main concern was ease of use, a theoretical option would be to keep the type definitions inside this repo but also have a DT entry that simply does import “@testing-library/jest-dom/extend-expect”; in the global scope. I’m not sure if that’s a common/recommended practice on DT, but it would make the setup instructions for this repo consistent with other projects and keep the actual typings co-located with the code.
Feel free to continue to maintain them yourself if you feel so inclined. I would love it if the types could somehow get added automatically though.
I just did the following:
npx create-react-app ts-jest-dom-example --typescript
cd ts-jest-dom-example
yarn add --dev @testing-library/react @testing-library/jest-dom
then I changed the src/App.test.tsx file to have this content instead of the default generated by CRA:
import React from 'react';
import { render } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import App from './App';
it('renders the expected content', () => {
const { container } = render(<App />);
expect(container).toHaveTextContent("Learn React");
});
Ran the tests with yarn test and it works. I added the assertion first and vscode's TS warnings immediately complained about toHaveTextContent not being recognized. But as soon as I typed the import line it removed the alert underline.

Granted, I could not make it work by centrally importing jest-dom in a single location (e.g. src/setupTests.ts) instead of having to import it in every single test file that uses it. Maybe that's what you'd like? Because if the above is enough, I'm not sure I'm getting what's the issue.
@jgoz would you happen to know if we can make the centralized import work? I'll try and dig into this tomorrow but now I need some sleep 😅
I could not make it work by centrally importing jest-dom in a single location (e.g. src/setupTests.ts) instead of having to import it in every single test file that uses it. Maybe that's what you'd like?
Precisely. And having it installed via @types/testing-library__jest-dom will make that work. So maybe all we'd need is:
import '@testing-library/jest-dom/extend-expect'I believe that should do it.
Nice! If that works that'd fix #45, your concerns, and my concerns about divergence of types vs lib.
Although I'll dig a bit more. jest-enzyme do not seem to be on DefinitelyTyped, they have the types in the same repo as we do, and their instructions to make the matchers work in TS are basically what we want to support (import once in setupTests.ts). I'll check if that indeed works in a local repo, and if it does, I'll dig into what's the difference.
I believe that theirs works because the setupTests.ts is a TypeScript file. But if it's a .js file it will not work properly. I could be wrong, but I feel like I read a comment in this repo that said that. Yep, this one.
Was your example of "it just works when I tried locally" working with the setupTest.js file being JS, importing jest-dom only in this setup file, and then using the custom matchers in TS test files?
Also, an update: it works for me having the centrally import in setupTest.ts. It's just vscode that does not recognizes it 🤔
Also, I do not think it's unreasonable to require, if you're already using TS, that your jest setupTest file be a TS file.
All of my code is regular JS. No TS. And my local test was working great with that when I created a node_modules/@types/testing-library__jest-dom.d.ts which simply did: import '@testing-library/jest-dom/extend-expect'
I do not think it's unreasonable to require, if you're already using TS, that your jest setupTest file be a TS file.
I agree with you. I'm talking about the experience for people not using TypeScript, but using an editor which supports TypeScript autocomplete (like VSCode).
Do you want to make extract it? Shall I make a pull request?
would you happen to know if we can make the centralized import work?
AFAIK, there’s no way to expose a global type definition _directly_ from an npm module, but it should work with the DT method described above. I won’t be able to test myself for a couple of days though.
Ok, I agree then to go with what Kent described above.
Regarding this concern from @jgoz
I’m not sure if that’s a common/recommended practice on DT
Indeed, their instructions for creating a new package pretty much assume you're going to add something of substance, not merely a redirector back to your own package. Let's hope that's ok anyway.
I have added a draft pull request for now: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/37688
I think the PR at DefinetlyTyped is good to go
-Merged. Guess, we can now update this package to refer the type definitions :)-
Looks like MSFT has closed the pull request, what shall we do?
I've reopened it and started a discussion. Let's see where it goes.
Just to summarize my understanding: you'd like to remove friction for people acquiring type definitions. @sheetalkamat closed the Definitely Typed PR as this package already has type definitions locally which could be exposed like so:
This change is not needed. The package can add
"types"field to the package and thats the desired way of adding types. Refer to https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/declaration%20files/Publishing.md
This is an entirely valid solution.
The alternative is doing what the React Testing Library did. i.e. dropping local definitions in favour of them being managed in DefinitelyTyped. That's what the linked PR to Definitely Typed by @weyert is about. If that was merged then a PR would follow for @testing-library/jest-dom which dropped the local type definitions and added a dependency for the generated @types/testing-library__jest-dom package.
More details in the suggestion from @kentcdodds here: https://github.com/testing-library/jest-dom/issues/123#issuecomment-521863263
To be entirely clear, my understanding is that the desire is to move to the latter solution (using DT) rather than the former. Is that correct? Or is exposing "types" via package.json being actively considered as well?
Yes, that's the idea to do it for all the @testing-library brother and sister packages. I thought it would be better to sort out the type definitions in TD first before making a PR here
I thought we were going to first attempt what @kentcdodds described above:
Precisely. And having it installed via @types/testing-library__jest-dom will make that work. So maybe all we'd need is:
- A contrib to DefinitelyTyped which simply does import '@testing-library/jest-dom/extend-expect'
- Add that as a dependency to this project so it gets auto-installed for folks.
I believe that should do it.
Now, I realize this may not be the kind of type definition packages expected and accepted in DT. If that's the case, and the only option is to entirely move the type definitions to DT and remove them from here, I already expressed my concerns about that above.
However, if completely moving the types to DT removes the friction in using types even for non-TS users, then so be it. But I'm a bit disappointed that no other solution exists. Does it not?
@johnnyreilly would the solution to keep types in this package, and adding a "types" entry to package.json solve @kentcdodds' concerns expressed here
I'm talking about the experience for people not using TypeScript, but using an editor which supports TypeScript autocomplete (like VSCode).
The fundamental reason these types need to be published on DT in some form is because they are global types that extend Jest's global types.
I.e., most people are probably not doing import {toHaveTextContent} from "@testing-library/jest-dom", they are probably just using expect(foo).toHaveTextContent(...) after configuring Jest.
As far as I know, it is not possible to publish global types from an npm package and have them "just work" when someone installs that package. This is because TypeScript's default type root is @types, so it will only ever look in node_modules/@types (and search up the directory hierarchy for the same) for types that will be _automatically included_.
So global typings like ours must be published to DT if we don't want to force the user would to do some kind of configuration (like they do now). But we also wanted to be able to keep maintenance of those types inside this repository so there is less chance that they go out of sync with the actual functionality, hence the PR that technically breaks the DT rules.
The flipside of having types on DT, whether directly or as a redirect, is that it might be confusing for new users who don't realize they need to add import "@testing-library/jest-dom/extend-expect" to a Jest configuration file. They could add the dependency and then toHaveTextContent magically appears in their editor, but running the tests would fail.
All of this could be avoided if Jest allowed the setupFilesAfterEnv to be written in TypeScript. That way, the setup file could be added to a user's tsconfig.json and we wouldn't need to publish the types to DT, since they would be explicitly imported as a one-time global import. But since that isn't possible, we have this set of tradeoffs to weigh.
To be clear, here's the tradeoff, we either:
A. Require JS folks to install the types to get autocomplete (most wont).
B. Make it automatic without config, but risk people getting autocomplete suggestions when jest-dom has not been configured properly.
When talking about risk, it's always good to consider how the likelihood and the impact. I would say the impact is a moderate-to-low impact of confusion only. It's pretty unlikely that this confusion would lead to a broken build/inability to deploy an app for example. Confusion as an impact is not great, so it'd be nice to avoid.
However, the likelihood is very low I would say. When someone installs @testing-library/jest-dom they'll probably be reading the instructions for setting things up and they'll add the configuration at that point.
So I'd say the risk is moderate-to-low impact and low risk. So the cost is low, and the benefit is high, IMO.
@johnnyreilly would the solution to keep types in this package, and adding a "types" entry to package.json solve @kentcdodds' concerns expressed here
I believe so yes. Either solution works AFAIK; both give the same good developer experience. It's just a choice around which way you'd like to go.
@johnnyreilly I don't think the "types" entry on its own would allow things to "just work", since they are global types, so DT is really the only option for automatic inclusion.
I haven't tried it but I have a feeling that either solution will work. I think that this being here:
will extend the jest namespace which is already pulled in globally. I'm not 💯% on this; but it's easy to test out. I recommend just adding the "types" entry and seeing if it works. If it doesn't then your decision is made 😄
I'm not 💯% on this; but it's easy to test out. I recommend just adding the
"types"entry and seeing if it works. If it doesn't then your decision is made 😄
I should have mentioned that I tried this out last night and it only worked if you added import "@testing-library/jest-dom/extend-expect" to a TS file that is included for compile.
To be clear, the suggestion is that if we add a "types" entry to the package.json of this project that'll make it work automatically as well? I tried that locally just now and it didn't seem to make any difference. I could have done it incorrectly though.
ah well then. Decision made!
To be clear, the suggestion is that if we add a "types" entry to the package.json of this project that'll make it work automatically as well?
Yes. Does the PR that @weyert has raised represent the desired way forward? This suggestion made me think that might not be the case...:
All of my code is regular JS. No TS. And my local test was working great with that when I created a
node_modules/@types/testing-library__jest-dom.d.tswhich simply did:import '@testing-library/jest-dom/extend-expect'
@kentcdodds
So I'd say the risk is moderate-to-low impact and low risk. So the cost is low, and the benefit is high, IMO.
Yep, makes sense to me. I just wanted to point out that automatically including the types was a potential source of confusion on the other end.
@johnnyreilly
Yes. Does the PR that @weyert has raised represent the desired way forward? This suggestion made me think that might not be the case...:
The original PR on DT was per the description you quoted. It looks like @weyert has since changed it to include all the types. The original PR would have allowed the definitions to be maintained inside of this repo (and was preferred by @gnapse).
Okay - well should the PR on definitely typed go in as is? Or should it be as @gnapse originally had it?
It would be nice to revert it and maybe flesh out the explanation for why we are breaking/bending the DT rules. There may be some timezone differences at play here, so I'm not sure how quickly @weyert can update the PR.
Cool - well let me know when you're ready to go and I'll review
Side question @jgoz - @basarat recently mentioned to me that back in the day you were one of the first maintainers of a TypeScript loader for webpack. And that his work with Pete Hunt, yourself and someone called "Andrey" all formed the prior art that @jbrantly eventually built upon to make ts-loader which I've been running for quite some time. Are you he? 😄
Sorry, I am confused. What the final decision we have made now? I am happy to update the PR when it's clear what's expected of me and the PR :)
I think the decision is my original suggestion:
testing-library__jest-dom to DefinitelyTyped@types/testing-library__jest-dom to @testing-library/jest-dom dependenciesAh! Sorry, lol, that's NOT the decision. The decision was my _second_ suggestion:
import '@testing-library/jest-dom/extend-expect'Sorry, let me double check, have been fighting with MobX+RTL too much today at work :)
You want to change the setup for this package from the other @testing-library packages?
Leave the type definition in this package, and add a dependency to @testing-library/jest-dom in the type definition ?
Yes, the maintainers here do want to keep the typings in this project, but we still want to make the typings automatic, which is why we're making this change. So the type defs stay here, but we want to add a type def to DT which basically just imports the type defs from this package, and then add the DT def module as a dependency in @testing-library/jest-dom. So there will be a bit of a circular dependency situation, but it should work without any trouble.
@johnnyreilly
Are you he? 😄
He is me 😄
Sounds odd to me but okay 😀
Let's ask what the DT people think of this plan before making the change
He is me 😄
Amazing! Small world. ts-loader says "hi!" https://github.com/TypeStrong/ts-loader 😄
@kentcdodds We wont accept the DT PR if the types continue to leave here.. We recommend that types are present either in package or on DT (definitely not in both places)
From https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/declaration%20files/Publishing.md
If your package is written in TypeScript then the first approach is favored. Use the --declaration flag to generate declaration files. This way, your declarations and JavaScript will always be in sync.
If your package is not written in TypeScript then the second is the preferred approach.
Oh just asked about this (https://github.com/DefinitelyTyped/DefinitelyTyped/pull/37688#issuecomment-523193247)
@sheetalkamat Having an @types package is the only way to include global type definitions simply by adding a dependency (without also adding some kind of configuration). We were hoping to be able to "have our cake and eat it" by co-locating maintenance of types and source code. Are there no exceptions for cases like these?
Considering that, and the fact that @gnapse would prefer to keep types in this package, then it's technically impossible to achieve this automatic type installation and therefore this issue should be closed.
Okay, closed the PR :)
@kentcdodds Let's wait to hear from @gnapse before closing this issue. If the DT hack is not an option, I would vote for moving the typings to DT.
I still think that having them in DT is suboptimal, but I too vote the way @jgoz did. It's a pity because I always thought that if libs had the types included it was always the best experience.
Update: For the record, with the type definitions externalized, I will probably not participate actively in any maintenance tasks for the types, aside from intervening in PRs, commenting, etc. It's a huge overhead to have to maintain the types elsewhere. Not to mention clone that huge repo :(
Yeah, it's unfortunate that this project falls into the narrow pit that doesn't have out-of-box support for included types. Hosting the types on DT shouldn't make a difference from the users' perspective and might improve the overall experience, but it will make maintenance more onerous.
Also, I suppose if someone is using a strict package manager like pnpm that doesn't hoist dependencies, they won't get the "just works" experience, either... but we're well within the 80/20 rule on that I'm sure.
I’m sort of hesitant to get involved here, but I just want to clear up one minor point of confusion which seems like it may be a motivator for this whole series of PRs and discussion:
To be clear, here's the tradeoff, we either:
A. Require JS folks to install the types to get autocomplete (most wont).
This is not necessarily true, at least for JS folks using VS Code under default settings. (I’m not sure about TS-Server-consuming plugins for other editors.) We perform so-called “automatic type acquisition” under the hood for JS projects only, installing @types packages to a cache location somewhere outside the actual project structure, and reference those in the language service to enable completions and other language-service-powered experience enhancements. So by default, whether you have your typings on DefinitelyTyped or included in your own library, JS folks, at least those using VS Code, will get the same rich TypeScript-powered experience.
I’m not currently prepared to declare that doing something else on top of this is a Bad Idea (neither from myself nor on behalf of the TypeScript team), but my personal leaning is that there may be some value in packages generally handling their typings in roughly the same way as the rest of the ecosystem. That leaves more doors open for us to implement more large-scale improvements in the future. And just to reiterate, I’m not suggesting that you shut this down or that explorations in this direction aren’t valuable. It seems like you all are going about this thoughtfully and carefully so far. Just another point to consider.
I have a few follow-up questions:
@gnapse I tried your example and yarn test fails without the import "@testing-library/jest-dom/extend-expect";. So it seems like the error from VS Code is correct.
@jgoz what do you mean by implicitly included for global typings? I don't know of any difference for TS between self-shipped types and DT-shipped types.
DefinitelyTyped does have a slight advantage when it comes to global typings, since they will be implicitly included for normal TS projects (those that don’t specify a types tsconfig option).
@types packages based on what you import. So having a package reference its own @types only helps TS projects.Specifically, I think the only advantage you're pursuing from having the types on DT is implicit inclusion of global typings. But I don't know whether (1) this package actually works without an import somewhere (2) DT actually behaves differently from types that ship in the own package.
A couple more points:
Update: Adding a types entry doesn't seem to work, though I might still be doing something wrong.
@kentcdodds Are you aware of Automatic Type Acquisition in VS Code? JS projects (those with no tsconfig) automatically install @types packages based on what you import.
Hey @sandersn!
I was aware of this advantage and have a question: does the automatic type acquisition in VS Code pay attention to major version numbers? i.e. Does it look for "@types/testing-library__jest-dom": "2.x" given a dependency of "@testing-library/jest-dom": "2.x"? Or just get the latest?
So having a package reference its own @types only helps TS projects.
Completely true; though I think that is still worthwhile; one yarn add instead of two and not having to discover / remember the quirky @types/testing-library__jest-dom double underscore convention
I talked to @sheetalkamat and confirmed that tsc does treat @types packages specially; global definitions are resolved without requiring an import. So that's a real advantage to having the types on Definitely Typed, and answers my question (2).
However, we agreed that it would be better to reflect the actual Javascript setup.js, and have instructions that suggest adding a setup.d.ts alongside the setup.js, with contents import "@testing-library/jest-dom/extend-expect";
. This is basically similar to the setup.ts instructions I saw for a similar library, except that the .d.ts doesn't emit any files when compiling.
This is an extra setup step, though, so I understand why you would want to dump the types into the global namespace to avoid it.
This is an extra setup step, though, so I understand why you would want to dump the types into the global namespace to avoid it.
Yes it is extra step but just like you are writing that import @testing-library/jest-dom/extend-expect one time in setup.js, you would be writing similar thing in d.ts. to inform the typescript compiler of presence of global so is more accurate representation and represents correct config
I tried your example and yarn test fails without the import "@testing-library/jest-dom/extend-expect";. So it seems like the error from VS Code is correct.
@sandersn assuming you're referring to what I mentioned here (comment above). Did you put the import in the src/setupTests.ts file? My point there was not that the import was not needed, but that it was sufficient to put it once in the tests setup file, and all tests would have access to the custom matchers. As you can see in the screenshot below, my test passes, yet vscode continues to mark the .toHaveTextContent as something that does not exist.

@gnapse is it cant see contents of setupTests in your case but here I followed your steps and things work as expected:

@gnapse Yep that is it. I missed that step.
Just to correct one of my earlier statements: Jest actually _does_ support using TypeScript for setup files if you use the ts-jest plugin. That means TypeScript projects can do as @gnapse and @sheetalkamat have done above and use setupTests.ts with the proper import and everything should work as expected, assuming setupTests.ts is referenced in tsconfig.json.
That means the actual reason we are considering these unorthodox changes is to offer a nice autocomplete experience for JavaScript users without having to learn about TypeScript configuration.
Based on my understanding of Automatic Type Acquisition, it uses packages listed in package.json (and can be refined by jsconfig.json) to determine which types to acquire from DT (please correct me if I'm wrong). That would work for most normal libraries, but the usage pattern for this library is where the complexity and potential rule bending come into play:
1) Importing jest-dom typically does not happen in the same file as the actual usage
2) Extending the global environment must be manually requested by importing jest-dom/extend-expect _somewhere_, so technically, our global typings should live in extend-expect.d.ts. But due to (1), the global typings will not be applied since there is no corresponding import in the test file.
This is why we were hoping to break the rules and keep the global typings located inside index.d.ts, fully realizing that it is technically not how the library is structured. Doing so would provide JS consumers with autocomplete without having to worry about TypeScript/VS Code configuration — only Jest configuration.
If TypeScript supported automatically importing global definitions from npm packages (via a globalTypes key or similar), we could keep our typings internal to the repo and not have to force the DT maintainers to spend time thinking about this 😉 (thank you all, by the way, for spending time to help us with this issue).
That means the actual reason we are considering these unorthodox changes is to offer a nice autocomplete experience for JavaScript users without having to learn about TypeScript configuration.
Thats not true. If your setup.js that you anyways have to write is part of your structure this should still work since that contains import of extend-expect.d.ts?
Extending the global environment must be manually requested by importing jest-dom/extend-expect somewhere, so technically, our global typings should live in extend-expect.d.ts. But due to (1), the global typings will not be applied since there is no corresponding import in the test file.
I dont agree with this approach since this is incorrectly representing the library and developer eg if missed writing that import in js file could run into the runtime error which is what we are trying to avoid. Having this auto added is good but that does not represent the setup step that is needed and hence i do not recoomend adding it to global by default.
@sheetalkamat
Thats not true. If your setup.js that you anyways have to write is part of your structure this should still work since that contains import of extend-expect.d.ts?
I just tested this locally with JS-only source and that only works if at least one of the following is true:
1) You have a jsconfig.json file that includes setupTest.js
2) The global definitions are defined in an index.d.ts file
In other words, omitting the jsconfig.json file and putting the global definitions in extend-expect.d.ts is not enough to get autocomplete in VSCode, even if it is imported somewhere in the solution structure.
Exactly, and the goal here is to make this whole thing automatic, which will happen if we put the types in DT and add them as a dependency.
Hello everyone! Happy to see this discussion as I've been going crazy trying to make the jest-dom typings just work in my VSCode (not using TS). They work if I manually import @testing-library/jest-dom/extend-expect file somewhere in my tests, however, I have it included in the jest.config.js file as follows:
setupFilesAfterEnv: [
'@testing-library/jest-dom/extend-expect',
'snapshot-diff/extend-expect'
],
In this case, it does not work. Interestingly enough, though, the typings for snapshot-diff are somehow picked up! I don't understand TS all that well so no idea why in their case it just works.
Edit:
Ah, snapshot-diff has the index.d.tsfile with type definitions so that's why it's seamless.
@janmyler Are you importing snapshot-diff somewhere in your tests too?
@jgoz No, it's only listed in the jest.config.js file as posted above.
Hi everyone.
VSCode user here. I've been wrestling with the same issue, and just to add my grain of salt:
File > New File
import '@testing-library/jest-dom/extend-expect';
From this setup, for some reason I'm getting the proper types _iff_ that separate tab is kept open somewhere. Close the tab, and toBeInTheDocument() and friends are back to any. This might work as a temporary alternative, but having to have that tab open at all times can be quite inconvenient. Still better than having to manually import the types in every single test file I guess...
_Edit_:
_Well, actually just having the definition file itself open somewhere is enough._
I've tried to include extend-expect.d.ts as a type root in tsconfig.json as follows
"typeRoots": [
"./node_modules/@types",
"./node_modules/@testing-library/jest-dom"
]
with no success though, I must be doing it wrong...
_Edit 2_
_Got the types to work by adding_
"files": [
"./node_modules/@testing-library/jest-dom/extend-expect.d.ts"
],
_to tsconfig.json_
I tried
"files": [
"./node_modules/@testing-library/jest-dom/extend-expect.d.ts"
],
without success. :/
Hi all, I think I've fixed this. Tested locally, and it works.
With this PR, importing either of the below into any ts file will solve the issue.
import '@testing-library/jest-dom';
import '@testing-library/jest-dom/extend-expect';
Please see https://github.com/testing-library/jest-dom/pull/135.
@mrmckeb Technically, the goal was to make the typings act as global typings, even for JS users, so that importing in a TS file (or adding a tsconfig file) was not required.
OK, I've updated the PR @jgoz - I think this may still work, even for JS. But haven't tested.
FYI, I've found the below works in a .d.ts file for me (probably .ts too).
import '@testing-library/jest-dom/extend-expect.d';
Meanwhile you can use these type definitions: https://github.com/vagonpidarasov/jest-dom
"dependencies": {
"@types/testing-library__jest-dom": "git://github.com/vagonpidarasov/jest-dom.git",
}
I removed my testUtils source folder from exclude option under tsconfig.json and the errors are gone during testing. however, when I launch the app it blows away

And this is working for me
The testUtils contains my jest.setup.ts which imports expect-extend

So, finally, how to make it work with VSCode autocomplete (I use typescript)?
So, finally, how to make it work with VSCode autocomplete (I use typescript)?
Make sure that you have jest config in include.
@kentcdodds The problem is not how to work automatically without config as this is a global typings. We should create better docs. I will try to create a PR with this docs, the only thing we need is to make sure that we are including the jest configuration on tsconfig.
Please remember that not everyone is using tsconfig, but they can still benefit from the automatic typings if they're using VSCode. That's what this issue is all about.
Gotcha.
Still, for those that are using tsconfig, this could help 🤔
I will still check if there is a solution for vscode for people who doesn't use tsconfig
I follow the @janmyler approach to finally make the types work for me in VSCode and WebStorm
in jest.config.js
module.exports = {
setupFiles: ["<rootDir>/jest.setup.js"],
setupFilesAfterEnv: ["<rootDir>/testing-library.setup.ts"]
in testing-library.setup.ts
import "@testing-library/jest-dom";
import "@testing-library/jest-dom/extend-expect";
Jest-dom sounds awesome, but I was not able to make this work...
Has anybody managed to have a typescript project with jest and jest-dom working properly?
Do you have a demo Gitbub repo?
I still get the [ts] Property 'toHaveTextContent' does not exist on type 'Matchers<void>'. anyerror.
Jest-dom sounds awesome, but I was not able to make this work...
Has anybody managed to have a typescript project with jest and jest-dom working properly?
Do you have a demo Gitbub repo?
I still get the[ts] Property 'toHaveTextContent' does not exist on type 'Matchers<void>'. anyerror.
Yes, but I don't have a public repo. The way to do it work is to have the setup jest file in your tsconfig file.
I wanted to mention to check @types/jest version. I was experiencing this issue and took a bit to follow along with the proposed solutions that are in this and other issues, but nothing worked. The solution for me was to update the version of @types/jest to 24.0.23, I was currently at 24.0.15.
I was trying to figure out what happened between those two versions to make extension methods like toBeInTheDocument() show as a method. It wasn't until I created a new project and checked the version numbers to see that was the big difference. I hope this helps if some runs across the error of
expect(...).toBeInDocument() is not a function
as well as, adding import "@testing-library/jest-dom/extend-expect"; to src/setupTest.ts
Ok so it seems the only way to solve this for good is to follow the original suggestion of externalizing the type definitions to DefinitelyTyped. Is that correct? If so, we should do it.
Ok so it seems the only way to solve this for good is to follow the original suggestion of externalizing the type definitions to DefinitelyTyped. Is that correct? If so, we should do it.
I actually did that in this PR: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/37792
But it is blocked because the DT team wants the typings to match the public API of the library, which in our case actually prevents the typings from being included automatically, defeating the purpose of moving them to DT.
The root of the problem is that the global Jest object is only patched when you import @testing-library/jest-dom/extend-expect. Which means the global typings should only live in a file called extend-expect.d.ts. But TypeScript only includes global typings for index.d.ts files in the @types/* root, so our global typings would not be automatically included.
Without new TS compiler flags or leniency from the DT team, I think the only way we can remove this friction is by moving the expect-extending side effects to index.js. In other words, doing import "@testing-library/jest-dom" would have the same effect as import "@testing-library/jest-dom/extend-expect". That way, we could move the typings to DT, add a dependency on them in this library, and close this issue.
moving the expect-extending side effects to index.js. In other words, doing
import "@testing-library/jest-dom"would have the same effect asimport "@testing-library/jest-dom/extend-expect"
Let's do it. Our whole purpose is to make this side effect on our import, and not to import anything into the module's namespace. I always wondered why we had this extend-expect thing. I think is a leftover from when this was extracted off dom-testing-library ages ago.
Agreed. I like the extend expect module because it makes things more clear when people are looking at the code, so if we could keep that around that would be great. But I'm fine having the main export do the same thing.
Oh sure, we should not remove it, it does not hurt and it would be a breaking change.
my 2 cents: nothing worked for me except the next config
include: [
"src",
"./node_modules/@testing-library/jest-dom/extend-expect.d.ts"
]
@jgoz @kentcdodds I created #175 to take care of https://github.com/testing-library/jest-dom/issues/123#issuecomment-556916129 above. Hopefully with that you can close DefinitelyTyped/DefinitelyTyped#37792, and subsequently this issue too.
I kinda made a rookie mistake by adding test files to the tsconfig.json exclude section (see below example). My reason was that I wanted to exclude them from being compiled in my build step. With the test files in the exclude section, no error where shown while running tests but my problem was really just VSCode complaining and not having auto completion. I split up all build related config into a tsonfig.build.json which extends from my main tsconfig.json file, thereby removing all below shown excludes from the main tsconfig.json file.
{
...
"exclude": [
"**/*.stories.ts",
"**/*.stories.tsx",
"**/*.spec.ts",
"**/*.spec.tsx",
"**/*.test.ts",
"**/*.test.tsx",
"src/setupTests.ts"
]
...
}
Definitions from setupTests.ts started working in my tests after npm i -D ts-jest and reloading IDE window.
"@types/jest": "^24.0.23",
"ts-jest": "^24.2.0",
@kentcdodds do we know when this will be released? I just started a new project following the configuration proposed by the library, and still facing errors:
import '@testing-library/jest-dom';
import '@testing-library/jest-dom/extend-expect';
import { cleanup } from '@testing-library/react';
afterEach(cleanup);
"@testing-library/jest-dom": "4.2.4",
"@testing-library/react": "9.4.0",
"@types/jest": "24.0.25",
"ts-jest": "24.3.0",
I just pinged the DefinitelyTyped PR, which supposedly can move forward after #175 got merged. Hopefully we'll have this soon 🤞
In case this can help anyone, a temp. solution that I am currently using while waiting for https://github.com/DefinitelyTyped/DefinitelyTyped/pull/37792 to get merged is to add:
/// <reference types="@testing-library/jest-dom/extend-expect" />
:tada: This issue has been resolved in version 5.0.1 :tada:
The release is available on:
npm package (@latest dist-tag)Your semantic-release bot :package::rocket:
Wahoo!
Confirmed that this is working:

Note that this is in an empty JavaScript test file. There's nothing else in this file. So once people install @testing-library/jest-dom they'll get the added TypeScript defs for free without any additional configuration.
Success! Thanks everyone!
Thanks for confirming it @kentcdodds. I was in the lookout for any possible issues.
Especial thanks to @jgoz, who did all the heavy lifting. I mostly merged some PRs along the way.
@jgoz are you on Twitter? I wanted to make a shoutout on Twitter about this.
I searched around a bit but couldn't find you @jgoz, https://twitter.com/kentcdodds/status/1219988754280013824
No sweat! I’m https://twitter.com/jmgozde. Thanks for the shoutout anyway
I'm still having this issue.
"@testing-library/jest-dom": "^5.11.4",
"@types/jest": "^26.0.13",
"jest": "^26.4.2"
with
import '@testing-library/jest-dom/extend-expect';
in setupTests.js and
setupFilesAfterEnv: ['./setupTests.js'],
in jest.config.js

...no autocomplete. The suggestions only show up when I import library directly into the test file. Red squiggles disappear.
@5tormTrooper can you try changing the import like this?
import '@testing-library/jest-dom';
Hi, If you still have some problem, it may be due to issue with typescript declaration merging. See this comment which provide some workaround : https://github.com/facebook/jest/issues/10642#issuecomment-802135590
Most helpful comment
Wahoo!
Confirmed that this is working:
Note that this is in an empty JavaScript test file. There's nothing else in this file. So once people install
@testing-library/jest-domthey'll get the added TypeScript defs for free without any additional configuration.Success! Thanks everyone!