This is the doc for custom render: https://testing-library.com/docs/react-testing-library/setup#custom-render. But no typescript version. I don't know what is the wrapper's type.
Hi there @ZhouHansen,
If you look at this line, you'll see its type: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/testing-library__react/index.d.ts#L37
Does it make sense now?
I've been trying to solve this all day and just came across this. An example for future readers:
function wrappedRender(
ui: ReactElement,
options?: CustomOptions
): CustomRenderResult {
// Wrap dispatch in a mock so it can be spied on.
const store = createStore(rootReducer, options?.state);
store.dispatch = jest.fn(store.dispatch);
function AllProviders({ children }: AllProvidersProps): ReactElement {
return (
<Provider store={store}>
{children}
</Provider>
);
}
const returns = render(ui, {
wrapper: AllProviders as ComponentType,
...options,
});
return { store, ...returns };
}
The key part being wrapper: AllProviders as ComponentType at the end.
I had to do something very similar or I get an error.
type TableProps = {
children: NonNullable<React.ReactNode>;
};
function Table({ children }: TableProps) {
return (
<table>
<tbody>{children}</tbody>
</table>
);
}
describe('row component', () => {
it('displays a row cells', () => {
const { getByText } = render(<tr><td>hello</td></tr>, {
wrapper: Table as React.FunctionComponent,
});
expect(getByText('hello')).toBeTruthy();
});
});
Error
error TS2769: No overload matches this call.
Overload 1 of 2, '(ui: ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)>, options?: Pick<...> | undefined): RenderResult<...>', gave the following error.
Type '({ children }: TableProps) => Element' is not assignable to type 'ComponentClass<{}, any> | FunctionComponent<{}> | undefined'.
Type '({ children }: TableProps) => Element' is not assignable to type 'FunctionComponent<{}>'.
Types of parameters '__0' and 'props' are incompatible.
Type '{ children?: ReactNode; }' is not assignable to type 'TableProps'.
Types of property 'children' are incompatible.
Type 'ReactNode' is not assignable to type 'string | number | boolean | {} | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<...>)> | ReactNodeArray | ReactPortal'.
Type 'undefined' is not assignable to type 'string | number | boolean | {} | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<...>)> | ReactNodeArray | ReactPortal'.
Overload 2 of 2, '(ui: ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)>, options: RenderOptions<...>): RenderResult<...>', gave the following error.
Type '({ children }: TableProps) => Element' is not assignable to type 'ComponentClass<{}, any> | FunctionComponent<{}> | undefined'.
Type '({ children }: TableProps) => Element' is not assignable to type 'FunctionComponent<{}>'.
34 wrapper: Table,
~~~~~~~
In the example above I think it would be easier to do the following, which leads to no typecasting:
import React from "react";
const Table: React.ComponentType = ({ children }) => {
return (
<table>
<tbody>{children}</tbody>
</table>
);
}
describe('row component', () => {
it('displays a row cells', () => {
const { getByText } = render(<tr><td>hello</td></tr>, {
wrapper: Table,
});
expect(getByText('hello')).toBeTruthy();
});
Looks like we've got solutions and there's nothing we can do in this repo to help further so I'll close this. Thanks!
Most helpful comment
I've been trying to solve this all day and just came across this. An example for future readers:
The key part being
wrapper: AllProviders as ComponentTypeat the end.