带有 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:添加位置状态以响应路由器组件