在带有 TypeScript 的 next.js 中使用 Router 的空安全方式

Posted

技术标签:

【中文标题】在带有 TypeScript 的 next.js 中使用 Router 的空安全方式【英文标题】:Null-safe way to use Router in next.js with TypeScript 【发布时间】:2019-04-27 08:08:54 【问题描述】:

next.js 建议使用以下模式来访问路由参数:

const Page = withRouter((props) => (
  <p>props.router.query.title</p>
))

现在的问题是,在 TypeScript 中,上面的代码会显示错误,因为 routerquery 可能未定义。它必须重写为

props.router!.query!.title

或作为

props.router &amp;&amp; props.router.query &amp;&amp; props.router.query.title

在我看来,这两种方式都不好。在第一个中,我们只是强制编译器忽略错误,而在其他情况下,代码会因不必要的噪音而膨胀。

有没有更好的方法来访问路由参数?

【问题讨论】:

你确定你已经正确安装了所有东西吗?我在下一个包中拥有所有必需的类型,因此访问查询字符串没有问题。导航 withRouter 导入时,它让我进入 with-router.d.ts 文件,您可以尝试导航并确认您最终在同一个文件中吗? 您使用的是哪个版本的 Next.js? 使用lodash 没有问题?如果没有,你可以_.get(props, "router.query.title"); 改为const router = useRouter(); 【参考方案1】:

javascript 中有一个 proposal for optional chaining,但似乎需要一段时间才能最终确定。

避免props.router!.query!.title 忽略类型检查错误是正确的。您必须按照您的建议有条件地检查现有属性:props.router &amp;&amp; props.router.query &amp;&amp; props.router.query.title

我通常创建一个辅助函数来接受一个对象并从中获取一个嵌套属性。或者更好的是,您可以使用现有的库,例如 lodash get:

import get from 'lodash/get'

...
const title = get(props, ['router', 'query', 'title'])
...

【讨论】:

【参考方案2】:

有一个 operator called optional chaining ?. 可以让您从对象链中读取值,而无需验证每个引用是否有效。它不会导致错误,而是返回 undefined。

所以你可以这样做:

const Page = withRouter((props) => (
    <p>props.router?.query?.title</p>
))

【讨论】:

以上是关于在带有 TypeScript 的 next.js 中使用 Router 的空安全方式的主要内容,如果未能解决你的问题,请参考以下文章

Next.js:在 getServerSideProps 中使用带有 TypeScript 的 next-redux-wrapper 调用 Thunks?

在带有 TypeScript 的 next.js 中使用 Router 的空安全方式

使用带有 TypeScript 的 next/image 时获取主机未配置错误

暗模式在带有 Nextjs 和 Typescript 的 Tailwind CSS V3 中不起作用

Storybook 在 React、Next.JS、Typescript 项目中找不到组件

在 TypeScript 和 Next.js 中使用绝对导入解析模块