Next.js TypeScript:无隐式类型传递动态URL参数至函数的问题
修复Next.js中useRouter参数传递的类型错误
问题根源在于router.query.blogId的类型为string | string[] | undefined,但useBlogQuery的id参数要求严格的string类型。以下是几种不使用隐式类型(如any断言)的修复方案:
方案一:显式检查参数有效性
通过条件判断收窄类型,同时处理参数为数组的场景(比如URL中重复传入同一参数的情况):
import { useRouter } from 'next/router' import { useBlogQuery } from '@graphql/generated' const router = useRouter() const blogId = router.query.blogId // 仅当参数为有效字符串时执行查询 if (typeof blogId === 'string') { const BlogQuery = useBlogQuery({ variables: { id: blogId }, }) } else if (Array.isArray(blogId) && blogId.length > 0) { // 数组类型取第一个有效元素 const BlogQuery = useBlogQuery({ variables: { id: blogId[0] }, }) } // 可添加else分支处理参数不存在的情况,比如渲染404页面
方案二:封装类型守卫函数复用逻辑
如果需要在多个组件中处理类似参数,可以封装类型守卫函数统一校验:
import { useRouter } from 'next/router' import { useBlogQuery } from '@graphql/generated' // 类型守卫:判断值是否为非空字符串 function isValidString(value: unknown): value is string { return typeof value === 'string' && value.trim() !== '' } // 处理参数,返回有效字符串或null function getValidId(param: string | string[] | undefined): string | null { if (isValidString(param)) { return param } else if (Array.isArray(param)) { return param.find(isValidString) || null } return null } const router = useRouter() const validBlogId = getValidId(router.query.blogId) if (validBlogId) { const BlogQuery = useBlogQuery({ variables: { id: validBlogId }, }) }
方案三:结合服务端渲染提前校验参数
如果页面支持服务端渲染(SSR)或静态生成(SSG),可以在getServerSideProps/getStaticProps中提前校验参数,直接传递给组件:
// 页面组件 import { useBlogQuery } from '@graphql/generated' export default function BlogPage({ blogId }) { const BlogQuery = useBlogQuery({ variables: { id: blogId }, }) // 页面渲染逻辑 } // 服务端获取并校验参数 export async function getServerSideProps(context) { const { blogId } = context.query let validBlogId = null if (typeof blogId === 'string') { validBlogId = blogId } else if (Array.isArray(blogId) && blogId.length > 0) { validBlogId = blogId[0] } if (!validBlogId) { return { notFound: true } // 返回404页面 } return { props: { blogId: validBlogId } // 传递已校验的字符串参数 } }
以上方案均通过类型收窄而非隐式类型转换解决类型不匹配问题,同时覆盖了参数可能为数组或undefined的边界情况。
内容的提问来源于stack exchange,提问作者Radovan Babjak
相关产品推荐
相关产品推荐

