如何为 useHitory() 覆盖非泛型类型,例如 @types/History?

Posted

技术标签:

【中文标题】如何为 useHitory() 覆盖非泛型类型,例如 @types/History?【英文标题】:How to override non-generic types such as @types/History for useHitory()? 【发布时间】:2021-01-18 22:23:57 【问题描述】:

我的目标是覆盖“历史”类型,所以我可以使用传递 eventKey 属性为 (eventKey) => history.push(eventKey),我无法从 useHistory() 覆盖 History 类型,它说“类型历史不是通用的”。我目前所做的解决方案是const history: any = useHistory(),但我相信它违背了类型的目的。

import  RouteConfigProps  from "app/routes/config";
import  RenderRoutes  from "app/routes/RenderRoutes";
import React from "react";
import  Nav, Navbar  from "react-bootstrap";
import  Link, useHistory  from "react-router-dom";

const Home: React.FC<routes: RouteConfigProps[]> = ( routes ) => 
  console.log("Home routes: ", routes)
  const history: History<> = useHistory();
  return (
    <div>
      <Navbar bg="light" expand="lg">
        <Navbar.Brand>Hi!</Navbar.Brand>
        <Navbar.Toggle aria-controls="basic-navbar-nav" />
        <Navbar.Collapse id="basic-navbar-nav">
          <Nav className="mr-auto" onSelect=(eventKey) => history.push(eventKey)>
            <Nav.Link eventKey="/home">Home</Nav.Link>
            <Nav.Link eventKey="/about">About</Nav.Link>
            <Nav.Link eventKey="/contact">Contact</Nav.Link>
            <Nav.Link eventKey="/motivational-letter">Motivational Letter</Nav.Link>
            <Nav.Link eventKey="/it-core-values">IT Core Values</Nav.Link>
          </Nav>
        </Navbar.Collapse>
      </Navbar>
      <RenderRoutes routes=routes />
    </div>
  );
;

export default Home;

【问题讨论】:

嘿,我觉得很有帮助***.com/questions/51152417/… 我不明白这个问题,但useHistory 钩子是通用的:useHistory&lt;HistoryLocationState = any&gt;()。如果您调用const history = useHistory&lt;MyHistoryType&gt;();,那么变量history 将具有History&lt;MyHistoryType&gt; 类型。但是您传递给history.push() 的论点不是通用的。它仍然具有To (defined here) 类型的be 【参考方案1】:

正如我在评论中解释的那样,useHistory() 钩子 通用的。我认为您遇到了错误,因为接口History 在多个地方有多个声明,有些是通用的,有些不是。假设您指的是内置浏览器 History 对象而不是路由器历史记录。所以最好将泛型应用于钩子调用而不是返回的对象。

这样做

const history = useHistory<MyHistoryType>(); // history has type History<MyHistoryType>

而不是这个

const history: History<MyHistoryType> = useHistory(); // gives error History is not generic

但打字稿问题是您传递给history.push() 的问题。传递的参数必须是 To 类型的 string 或特定对象 PartialPath,并且不依赖于 History 的泛型。

作为onSelect 传递给Nav 组件的参数必须是SelectCallback 类型,其定义为:

type SelectCallback = (eventKey: string | null, e: React.SyntheticEvent<unknown>) => void

你看到不匹配了吗? eventKey 可以是stringnull,但history.push() 只能接受string 而不能接受null。所以你需要在调用history.push(eventKey)之前使这个条件过滤掉null

const onSelect = (eventKey: string | null) => 
    if (eventKey !== null)  
        history.push(eventKey); 
    

这将解决您的打字稿错误。

【讨论】:

过滤器!这是解决我问题的关键。你知道如何覆盖.push() 类型吗? @kidfrom 你想要达到什么目的?有一些方法可以抑制打字稿错误,但如果你这样做,你可能最终会遇到运行时错误。如果您将某些无法理解的内容推送到路由器历史记录中,它会阻塞。

以上是关于如何为 useHitory() 覆盖非泛型类型,例如 @types/History?的主要内容,如果未能解决你的问题,请参考以下文章

泛型集合与非泛型集合的异同

LINQ学习系列-----3.1 查询非泛型集合

为啥 C# 无法从非泛型静态方法的签名推断泛型类型参数类型?

无法专门化非泛型类型 ResponseSerializer

无法专门化非泛型类型“Set”

用于扩展非泛型类型的尾随 where 子句