Incorrect TypeScript overload signature for React Testing Library example snippet with React Router

Viewed 309

the React Testing Library documentation has this example for writing unit tests for components that use React Router. More specifically, it mentions this boilerplate snippet:

// test utils file
function renderWithRouter(
  ui,
  {
    route = '/',
    history = createMemoryHistory({ initialEntries: [route] }),
  } = {}
) {
  const Wrapper = ({ children }) => (
    <Router history={history}>{children}</Router>
  )
  return {
    ...render(ui, { wrapper: Wrapper }),
    // adding `history` to the returned utilities to allow us
    // to reference it in our tests (just try to avoid using
    // this to test implementation details).
    history,
  }
}

Based on the type signature of the functions createMemoryHistory from the history package and render from the @testing-library/reactpackage, which is:

export type RenderResult<Q extends Queries = typeof queries> = {...}

export function render(ui: React.ReactElement, options?: Omit<RenderOptions, 'queries'>): RenderResult;
export function render<Q extends Queries>(ui: React.ReactElement, options: RenderOptions<Q>): RenderResult<Q>;

I tried to convert the above test util code snippet to TypeScript code. I came up with this:

import { Queries, render, RenderOptions, RenderResult, queries } from "@testing-library/react"
import { createMemoryHistory, LocationState, MemoryHistory } from "history"
import React from "react"
import { Router } from "react-router-dom"

export type RouterOptions<S = LocationState> = {
    route: string,
    history?: MemoryHistory<S>
}

export type RenderWithRouterResult<Q extends Queries, S = LocationState> = RenderResult<Q> & {history: MemoryHistory<S>}

export function renderWithRouter<S>(ui: React.ReactElement, options?: Omit<RenderOptions, "queries">, routerOptions: RouterOptions<S> = {route: "/"}): RenderWithRouterResult<typeof queries,S>
export function renderWithRouter<Q extends Queries, S>(ui: React.ReactElement, options: RenderOptions<Q>, routerOptions: RouterOptions<S> = {route: "/"}): RenderWithRouterResult<Q,S> {
    const routerHistory = routerOptions.history || createMemoryHistory({ initialEntries: [routerOptions.route] })
    const routerElement: React.ComponentType = ({ children }) => (
        <Router history={routerHistory}>{children}</Router>
    )
    return {
        ...render(ui, { wrapper: routerElement }),
        // adding `history` to the returned utilities to allow us
        // to reference it in our tests (just try to avoid using
        // this to test implementation details).
        history: routerHistory,
    }
}

and some crazy type errors for both the overload signature and the return type, that are too long for vscode to display them fully.

Could anybody please help me to correct the types and overloads above, please?

0 Answers
Related