带有 typescript 的 React 路由器 v5 上所需的 url 参数,可以是未定义的

Posted

技术标签:

【中文标题】带有 typescript 的 React 路由器 v5 上所需的 url 参数,可以是未定义的【英文标题】:required url param on React router v5 with typescript, can be undefined 【发布时间】:2020-03-23 22:29:14 【问题描述】:

我正在使用带有 TypeScript 的 react-router v5.1 并具有以下路由配置:

<Router basename="/" hashType="slash">
    <Switch>
        <Route path="/token/:tokenName">
            <TokenPage />
        </Route>
    </Switch>
</Router>

我尝试使用 useParams 钩子访问组件中的 url 参数(tokenName),如下所示:

const TokenPage: FC<TokenPageProps> = props => 
    const  tokenName  = useParams()
    ...


但是,typescript 认为 tokenName 参数可以是未定义的:

这没有意义,因为如果 URL 中缺少参数,react router 将不会匹配此路由。

在这种情况下我该如何解决打字问题?

【问题讨论】:

【参考方案1】:

在这种情况下,您的TokenPage 代码不知道它正在被Route 包装。你是对的,如果 URL 不包含正确的参数,你的组件将不会被渲染。但是 Typescript 并没有意识到这一点。

你得到的默认类型是正确的,你应该在使用它之前检查值。

如果您想覆盖输入,useParams 是通用的,并接受指定返回值类型的类型。

interface ParamTypes 
  tokenName: string

const  tokenName  = useParams<ParamTypes>()

编辑 09/29/20

useParams 的 latest typing 已更改。

export function useParams<Params extends  [K in keyof Params]?: string  = >(): Params;

如您所见,新的默认值为 ,这并不意味着包含任何键,但通用约束确实假定值的类型为 string

所以下面这行现在会产生Property 'tokenName' does not exist on type ''. TypeScript 错误。

const  tokenName  = useParams()

要解决此问题,您可以像第一个示例中那样使用已知参数输入 useParams,或者像这样输入:

const  tokenName  = useParams<Record<string, string | undefined>>()

【讨论】:

基于上次更新,您需要添加以下接口作为类型断言的替代方法:interface ParamTypes tokenName?: string; @NicolasBouvrette useParams 的通用类型不会影响您是否应该期望字段可以为空。你可以和任何一个一起去。如果您确定它会被定义,这基本上就是问题在这里所要求的,您可以在没有? 的情况下保留它,并避免到处检查它。【参考方案2】:

使用原来的重写类型的思想,不需要创建新的命名接口,直接在类型参数中就可以了:

const  tokenName  = useParams< tokenName: string >();

【讨论】:

【参考方案3】:

你可以的

type ParamTypes 
  tokenName: string

const  tokenName  = useParams<ParamTypes>()

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于带有 typescript 的 React 路由器 v5 上所需的 url 参数,可以是未定义的的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Typescript 从 react-router-dom 访问路由参数?例如:`/some-route/:slug`

如何在基于 Typescript 的 React Web 应用程序中具有参数的 Route 元素中传递其他道具

如何将 React 路由器功能转换为 Typescript?

React Typescript:添加位置状态以响应路由器组件

带有 React、TypeScript 和 Webpack 的空白页面

带有 React.createContext 的 Typescript HOC