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

React TS中onClick类型报错:事件对象与自定义参数冲突

问题

尝试在自定义Button组件的onClick处理函数中传入自定义变量,功能可正常运行,但TypeScript抛出类型错误。

类型定义

export type ButtonType = {
  name: string;
  buttonStyle: string;
  onClick?: (id: number) => void;
};

可复用Button组件

return (
  <button
    type="submit"
    className={buttonTypeStyle(buttonStyle)}
    onClick={onClick}
  >
    {name}
  </button>
);
};

UrlList组件中的使用

const handleOnCLick = (id: number) => {
  return copiedUrlId !== id ? dispatch(setCopiedAction({ id })) : 0;
};

return (
  <section className={style.container}>
    <ul className={style.container__urlList}>
      {urls.length > 0 &&
        urls.map((url: any) => {
          return (
            <li key={urls.id} className={style.container__url}>
              <p>original url</p>
              <hr />
              <div className={style.container__urlDivider}>
                <p>{url.shortenUrl}</p>
                <Button
                  name={`${copiedUrlId === url.id ? "Copied!" : "Copy"}`}
                  buttonStyle={
                    copiedUrlId === url.id
                      ? "smallSquareCopied"
                      : "smallSquare"
                  }
                  onClick={() => handleOnCLick(url.id)}
                />
              </div>
            </li>
          );
        })}
    </ul>
  </section>
);

报错信息

TS2322: Type '((id: number) => void) | undefined' is not assignable to type 'MouseEventHandler<HTMLButtonElement> | undefined'.
  Type '(id: number) => void' is not assignable to type 'MouseEventHandler<HTMLButtonElement>'.
    Types of parameters 'id' and 'event' are incompatible.
      Type 'MouseEvent<HTMLButtonElement, MouseEvent>' is not assignable to type 'number'.
    16 |       type="submit"
    17 |       className={buttonTypeStyle(buttonStyle)}
  > 18 |       onClick={onClick}
       |       ^^^^^^^
    19 |     >
    20 |       {name}
    21 |     </button>

推测是原生onClick默认传递event对象,TypeScript将其与自定义变量id混淆导致类型冲突,该如何解决?


解决方案

核心问题是:原生<button>的onClick期望接收MouseEventHandler<HTMLButtonElement>类型(即接收MouseEvent参数的函数),但你定义的ButtonType中onClick是接收number类型参数的函数,两者类型不匹配。以下是三种可行解决方法:

方法一:修正ButtonType的onClick类型(推荐)

你在UrlList中传入的onClick是() => handleOnCLick(url.id)——这是一个无参数函数,已经通过闭包绑定了url.id。因此直接修改ButtonType的onClick类型为无参数函数,即可完美匹配:

export type ButtonType = {
  name: string;
  buttonStyle: string;
  onClick?: () => void;
};

Button组件代码无需修改,因为无参数函数可以兼容原生onClick(原生会传递event,但函数可选择不接收),TypeScript会自动通过类型检查。

方法二:在Button组件中包装传入的onClick

如果需要保留原ButtonType的类型定义,可在Button组件内将传入的onClick包装成符合原生事件要求的函数,忽略原生event参数:

return (
  <button
    type="submit"
    className={buttonTypeStyle(buttonStyle)}
    onClick={() => {
      onClick?.();
    }}
  >
    {name}
  </button>
);
};

方法三:让onClick同时兼容event和自定义参数

若需要在Button组件中同时获取原生event和自定义id,可调整类型定义并修改组件逻辑:

  1. 更新类型定义:
export type ButtonType = {
  name: string;
  buttonStyle: string;
  onClick?: (event: React.MouseEvent<HTMLButtonElement>, id: number) => void;
  id?: number;
};
  1. 修改Button组件:
return (
  <button
    type="submit"
    className={buttonTypeStyle(buttonStyle)}
    onClick={(event) => {
      onClick?.(event, id);
    }}
  >
    {name}
  </button>
);
};
  1. 在UrlList中使用:
<Button
  name={`${copiedUrlId === url.id ? "Copied!" : "Copy"}`}
  buttonStyle={copiedUrlId === url.id ? "smallSquareCopied" : "smallSquare"}
  id={url.id}
  onClick={(event, id) => handleOnCLick(id)}
/>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 01:45:02