extend-expect throws a couple more things onto extend and of course typescript doesnt like that. Is there a way to also expand the types or otherwise modify index.d.ts to accommodate for the changed type signature of expect?
for google purposes this is the error i get:
[ts] Property 'toHaveTextContent' does not exist on type 'Matchers<void>'.
any
No idea. Perhaps there are clues in jest-extended?
i just scanned through their code, they dont even have types -at all- so they're actually worse off than react-testing-library 馃槀
ok so i worked out how to use them, we might want to 1) document this 2) put this into the index.d.ts.
// standard stuff from the example
import * as React from 'react';
import {render, Simulate, wait} from 'react-testing-library'
// extends
import 'react-testing-library/extend-expect';
interface ExtendedMatchers extends jest.Matchers<void> {
toHaveTextContent: (htmlElement: string) => object;
toBeInTheDOM: () => void;
}
//usage example
test('displays greeting when clicking Load Greeting', async () => {
const { getByLabelText, getByText, getByTestId, container } = render(
<Tooltip label="hello world">Child</Tooltip>
);
(getByLabelText('name') as HTMLInputElement).value = 'Mary';
(expect(getByTestId('greeting-text')) as ExtendedMatchers).toHaveTextContent(
'Hello Mary'
);
})
let me know how you want this to proceed kent. i can take care of this entirely in userland, but you could help a very little bit by including this in the index.d.ts
Seems fine to me. I don't maintain the typings myself, but if you want to help take over maintaining the typings that'd be super.
I would be happy to do that. I just realized though that any types that this lib ships with would bind it to a particular testing frame work, eg jest. so this is probably actually best solved in userland. I will just submit a minor documentation PR for a typescript section.
Actually, _this_ file _is_ specific to Jest so if there's a way to only apply these types if this file is utilized then that'd be fine.
@tsiq-swyx Thanks for the fix. @kentcdodds Somehow, I'm not getting the notifications on this project, even though I'm watching it ;) Checking manually now :)
Just passing by looking for solution for a similar issue. I've found out a solution. You can probably fix the issue by putting the following code in the typings of react-testing-library:
declare namespace jest {
interface Matchers<R> {
toHaveTextContent: (htmlElement: string) => object;
toBeInTheDOM: () => void;
}
interface Expect {
toHaveTextContent: (htmlElement: string) => object;
toBeInTheDOM: () => void;
}
}
It uses Declaration Merging.
Ok I realized that it seems that the issue is already fixed here: https://github.com/gnapse/jest-dom/pull/11
I just ran into the same issue and found a nice solution, similar to what @michalstocki was suggesting, but wanted to clarify it more. If you create a file called jest.d.ts, its namespace declaration will be merged with the one provided by Jest itself. For example, for a custom matcher
expect('string').toEndWith('ing');
you would extend the namespace
// custom jest.d.ts somewhere in the source
declare namespace jest {
interface Matchers<R> {
toEndWith(value: string): CustomMatcherResult;
}
}
and implement
expect.extend({
toEndWith: (actualString: string, expectedEnding: string) => ({
message: `expected that ${actualString} ends with ${expectedEnding}`,
pass: actualString.endsWith(expectedEnding),
}),
});
Thought I'd leave this here because this is the first search result that came up for me :nerd_face:
@simonhaenisch thanks. Since jest is not an imported module, in jest.d.ts, I also had to declare this as a global, so:
declare global {
namespace jest {
interface Matchers<R> {
toEndWith(value: string): CustomMatcherResult;
}
}
}
If anyone else ends up here after running through the stuff from TestingJavascript.com and getting an error about react-testing-library's matchers not existing on type 'Assertion', the issue is actually due to a conflict between Jest and Cypress, and has nothing to do with react-testing-library. The easiest fix I found was just adding the cypress folder to the excludes in my tsconfig.json in the root of my project:
{
...lots of config,
"exclude": [
"node_modules",
"webpack",
"jest",
"cypress",
]
}
Hopefully this helps someone!
I couldn't make any of the solutions above to work, so I went for a quick and dirty solution:.
const myExpect: any = Object.assign(expect);
myExpect.extend({
...
I couldn't make any of the solutions above to work, so I went for a quick and dirty solution:.
const myExpect: any = Object.assign(expect); myExpect.extend({ ...
In that case, one other way is to simply change the extension to .js if type checking is not that crucial in that test :)
None of the above options seemed to work for me (I'm using WebStorm 2019.2 and jest-dom 4.1.0).
I had to put the following in my test file.
I could NOT put these imports in a separate setupTests.ts or *.d.ts, that didn't work
import '@testing-library/jest-dom'
import '@testing-library/jest-dom/extend-expect'
Then I stopped getting warnings like "Error:(27, 16) TS2339: Property 'toBeVisible' does not exist on type 'Matchers
Most helpful comment
@simonhaenisch thanks. Since jest is not an imported module, in jest.d.ts, I also had to declare this as a global, so: