如何使用Typescript将Next.js Link封装为自定义React组件并解决类型报错
错误原因
你错误地将React.DetailedReactHTMLElement作为组件的Props类型,这个类型是用来描述DOM元素实例对象的,不是React组件接收的入参类型,因此TS会要求你传入type/ref/props/key这些不属于组件入参的属性,触发类型报错。
修复方案
- 用
React.ComponentProps<typeof Link>自动获取Next.js Link组件的所有原生合法属性,不需要手动枚举事件、href等属性,避免遗漏和类型错误。 - 将原生Link属性和你自定义的
title、link属性交叉,作为组件的Props类型。 - 可选优化:如果需要透传ref给Link组件,使用
React.forwardRef包裹组件实现ref透传。
修改后完整代码
import style from "./Button.module.css"; import Link from "next/link"; // 定义组件Props类型:继承Link所有原生属性 + 自定义属性 type ButtonProps = React.ComponentProps<typeof Link> & { title?: string; link?: string; } export const Button: React.FC<ButtonProps> = ({ title, children, link, ...rest }) => ( // 优先用传入的link作为href,兼容原生href属性 <Link href={link ?? rest.href} {...rest}> {title ?? children} </Link> );
如果需要强制用户只能传link、不能使用原生href属性,可以调整Props定义如下:
// 从原生属性中排除href,同时将link设为必填项 type ButtonProps = Omit<React.ComponentProps<typeof Link>, 'href'> & { title?: string; link: string; }
如果需要支持ref透传,使用如下版本:
import style from "./Button.module.css"; import Link from "next/link"; type ButtonProps = React.ComponentProps<typeof Link> & { title?: string; link?: string; } export const Button = React.forwardRef<HTMLAnchorElement, ButtonProps>(({ title, children, link, ...rest }, ref) => ( <Link ref={ref} href={link ?? rest.href} {...rest}> {title ?? children} </Link> )); Button.displayName = "Button";
修改后你原来的调用代码不需要做任何调整,不会再触发类型报错。
内容的提问来源于stack exchange,提问作者user16911633
相关产品推荐
相关产品推荐

