首页 > 解决方案 > 使用 React 路由器的 React 测试库示例片段的 TypeScript 重载签名不正确

问题描述

React 测试库文档有这个示例,用于为使用 React 路由器的组件编写单元测试。更具体地说,它提到了这个样板代码片段:

// 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,
  }
}

基于createMemoryHistory来自history包和render来自@testing-library/react包的函数的类型签名,即:

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>;

我试图将上面的测试 util 代码片段转换为 TypeScript 代码。我想出了这个:

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,
    }
}

以及重载签名和返回类型的一些疯狂的类型错误,对于 vscode 来说太长而无法完全显示它们。

有人可以帮我纠正上面的类型和重载吗?

标签: typescripttypescript-genericsreact-testing-library

解决方案


推荐阅读