Next.js项目从JS迁移到TS时className不存在的类型错误如何解决?
问题排查
- 你定义的
NavLinkProps中错误声明了props: ReactNode字段,代码中{ href, exact, children, ...props }的...props是未被显式声明的剩余属性集合,并不是你手动定义的props字段,这个错误声明导致TS判定剩余props的类型为{ props: ReactNode },自然不存在className属性。 - 没有给透传给
<a>标签的属性定义对应类型,TS无法识别透传属性中包含className等锚点元素原生属性。 - 代码末尾多了一个多余的闭合大括号,属于语法错误。
解决方案
修正后的完整代码如下:
import { useRouter } from 'next/router' import Link from 'next/link' import { ReactNode, HTMLProps } from 'react' // 继承a标签所有原生属性,叠加自定义属性 interface NavLinkProps extends HTMLProps<HTMLAnchorElement> { href: string exact?: boolean children: ReactNode } function NavLink({ href, exact = false, children, ...props }: NavLinkProps) { const { pathname } = useRouter() const isActive = exact ? pathname === href : pathname.startsWith(href) if (isActive) { // 兼容className初始不存在的场景,避免出现undefined active的异常 props.className = props.className ? `${props.className} active` : 'active' } return ( <Link href={href}> <a {...props}>{children}</a> </Link> ) } export { NavLink }
改动说明:
- 移除错误的
props: ReactNode字段,让...props自动匹配继承自锚点元素的所有属性,TS会自动识别className、id、style等原生属性 - 让
NavLinkProps继承HTMLProps<HTMLAnchorElement>,获得所有a标签原生属性的类型支持 - 把默认值直接写到参数解构位置
exact = false,比单独声明defaultProps的类型兼容性更好 - 修复多余大括号的语法错误
- 优化className拼接逻辑,避免初始无className时出现undefined的问题
内容的提问来源于stack exchange,提问作者Gravy59
相关产品推荐
相关产品推荐

