You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js TypeScript项目自定义LinkButton组件Props解构报错求助

问题分析与解决

这不是size类型的问题,也不是TypeScript的Bug,核心原因是多类型交叉后,TypeScript无法正确推断剩余属性rest的对象类型,再加上代码里的写法错误,最终触发了报错。

具体原因

当你把ButtonProps、LinkProps和HTMLProps<HTMLAnchorElement>交叉合并时:

  1. HTMLProps<HTMLAnchorElement>本身包含onClick属性(类型为MouseEventHandler<HTMLAnchorElement>),而你的ButtonProps里也定义了onClick: () => void,两个类型交叉后产生冲突,干扰了TypeScript对rest的类型解析。
  2. 手动解构NextLink的属性后,剩余的rest被TS判定为非纯对象类型,于是抛出Rest types may only be created from object types错误。移除size后TS的类型推断逻辑刚好避开了冲突判定,错误暂时消失,但这只是巧合,并非根本解决方法。

修正方案

1. 修复Button组件的调用错误

你代码里的<Button ...ButtonProps/>写法错误,应该把rest中属于Button的属性传递给组件:

<Button {...rest} />

2. 明确rest类型,规避交叉冲突

用Omit工具类型排除LinkProps的属性,同时去掉HTMLProps中和ButtonProps冲突的字段,让TS清晰识别rest的纯对象类型:

import NextLink, { LinkProps } from 'next/link'
import { HTMLProps, FC, MouseEventHandler } from 'react'
import { GlobalColorsType } from '../../types'
import Button from './Button'

type ButtonProps = {
  type: GlobalColorsType
  size: 'xs' | 's' | 'm' | 'l' | 'xl'
  onClick: MouseEventHandler<HTMLButtonElement> // 建议和Button组件的onClick类型对齐,避免冲突
  className?: string
  id?: string
  style?: any
}

// 排除LinkProps属性,同时移除HTMLProps中和ButtonProps冲突的onClick
type LinkButtonProps = Omit<HTMLProps<HTMLAnchorElement>, 'onClick'> & ButtonProps & LinkProps

const LinkButton: FC<LinkButtonProps> = ({
  as,
  children,
  href,
  replace,
  scroll,
  shallow,
  passHref,
  ...rest // TS现在能明确这是纯对象类型
}) => (
  <NextLink
    as={as}
    href={href}
    passHref={passHref}
    replace={replace}
    scroll={scroll}
    shallow={shallow}
  >
    <a {...rest}>
      <Button {...rest} />
    </a>
  </NextLink>
)

export default LinkButton

3. 可选优化:拆分属性传递

如果不想用Omit,可以手动拆分Button和a标签的属性,避免类型混淆:

const LinkButton: FC<LinkButtonProps> = ({
  as,
  children,
  href,
  replace,
  scroll,
  shallow,
  passHref,
  // 手动提取Button所需属性
  type,
  size,
  onClick,
  // 提取a标签所需属性
  className,
  id,
  style,
  ...anchorRest
}) => (
  <NextLink
    as={as}
    href={href}
    passHref={passHref}
    replace={replace}
    scroll={scroll}
    shallow={shallow}
  >
    <a className={className} id={id} style={style} {...anchorRest}>
      <Button type={type} size={size} onClick={onClick} className={className} id={id} style={style} />
    </a>
  </NextLink>
)

内容的提问来源于stack exchange,提问作者robicano22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 14:06:24