I'm trying to build a convenience function that allows me to pass a react component and have it render the component with all of the options and route specifications that I want that I pass it wrapped around a <BrowserRouter> for unit testing.
The problem is when I try to pass Wrapper function into react testing library's render() (see rtlRender() below), I'm getting an error from TypeScript stating the following
No overload matches this call. Overload 1 of 2, '(ui: ReactElement<any, string | JSXElementConstructor>, options: RenderOptions<Queries, HTMLElement>): RenderResult<...>', gave the following error. Type '({ children }: Props) => JSX.Element' is not assignable to type 'ComponentType<{}> | undefined'. Type '({ children }: Props) => JSX.Element' is not assignable to type 'FunctionComponent<{}>'. Types of parameters '__0' and 'props' are incompatible. Type '{ children?: ReactNode; }' is not assignable to type 'Props'. Types of property 'children' are incompatible. Type 'ReactNode' is not assignable to type 'ReactChildren'. Type 'undefined' is not assignable to type 'ReactChildren'. Overload 2 of 2, '(ui: ReactElement<any, string | JSXElementConstructor>, options?: Omit<RenderOptions<typeof import("/Users/myuser/dev/myapp/container/node_modules/@testing-library/dom/types/queries"), HTMLElement>, "queries"> | undefined): RenderResult<...>', gave the following error. Type '({ children }: Props) => JSX.Element' is not assignable to type 'ComponentType<{}> | undefined'. Type '({ children }: Props) => JSX.Element' is not assignable to type 'FunctionComponent<{}>'.ts(2769) index.d.ts(41, 3): The expected type comes from property 'wrapper' which is declared here on type 'RenderOptions<Queries, HTMLElement>' (property) RenderOptions<Queries, HTMLElement>.wrapper?: React.ComponentType<{}> | undefined
Here's my code
import React from 'react';
import { Queries, render as rtlRender } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';
import { RenderResult } from '@testing-library/react/types';
/* Type Definitions */
type Route = {
state: Record<string, unknown>;
title: string;
location: string;
};
type Props = {
children: React.ReactChildren;
};
/* Helper Functions */
export function render(ui: JSX.Element, options: { route: Route }): RenderResult<Queries, HTMLElement> {
const { route } = options;
window.history.pushState(route?.state ?? null, route?.title ?? 'Root', route?.location ?? '/');
const Wrapper = ({ children }: Props) => {
return <BrowserRouter>{children}</BrowserRouter>;
};
return rtlRender(ui, { wrapper: Wrapper, ...options });
}
From what I understand, it's telling me that whatever Wrapper() returns doesn't fit the description of a React class component or functional component. This seems weird to me because you can tell from the code, Wrapper() should return a functional component.
I tried to assign Wrapper() to type React.FC<Props>, but TypeScript states that React.FC<Props> is not of type React.ComponentType which made me even more confused.
I'm still new to TypeScript so throwing in all these React types is confusing me even more. I'm hoping for some guidance on this.