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

MUI中如何正确为ForwardedRef编写TypeScript类型

问题背景

你需要实现自定义转发ref的复选框组件,传入DataGrid作为基础复选框使用,当前实现中使用了as React.RefObject<HTMLButtonElement>类型断言绕开TypeScript检查,你希望找到更规范的实现方案,同时确认这类场景下类型断言是否属于可接受的写法。

现有实现代码
const CustomCheckbox = ({
  checkboxRef,
  ...props
}: {
  checkboxRef: React.ForwardedRef<unknown>;
}) => (
  <Checkbox
    {...props}
    ref={checkboxRef as React.RefObject<HTMLButtonElement>}
    sx={{
      color: "#363636",
      "&.Mui-checked": {
        color: "#363636"
      }
    }}
  />
);

const ForwardCustomCheckbox = forwardRef((props, ref) => {
  return <CustomCheckbox {...props} checkboxRef={ref} />;
});


<DataGrid
  ...
  components={{
    BaseCheckbox: ForwardDarkCheckbox
  }}
/>

注:现有代码中ForwardDarkCheckbox属于笔误,实际应为定义的ForwardCustomCheckbox

最优实现方案

你当前代码需要写类型断言的核心原因,是没有给forwardRef传入正确的泛型参数,还额外加了一层把ref类型标记为unknown的中间组件,主动丢失了类型信息。完全可以去掉冗余的中间层,直接通过泛型约束实现全链路类型安全,不需要任何类型断言:

import { forwardRef } from 'react';
import { Checkbox, CheckboxProps } from '@mui/material';

// forwardRef泛型参数顺序:<ref指向的元素类型, 组件接收的props类型>
const ForwardCustomCheckbox = forwardRef<HTMLButtonElement, CheckboxProps>((props, ref) => {
  return (
    <Checkbox
      {...props}
      ref={ref}
      sx={{
        color: "#363636",
        "&.Mui-checked": {
          color: "#363636"
        }
      }}
    />
  );
});

// 传入DataGrid直接使用即可
<DataGrid
  // 其余业务属性
  components={{
    BaseCheckbox: ForwardCustomCheckbox
  }}
/>

如果确实需要拆分中间组件(比如要在复选框外层加额外的逻辑、样式封装),不要把中间组件接收的ref类型设为unknown,直接标注正确的类型即可,同样不需要断言:

import { forwardRef, ForwardedRef } from 'react';
import { Checkbox, CheckboxProps } from '@mui/material';

const CustomCheckbox = ({
  checkboxRef,
  ...props
}: CheckboxProps & {
  checkboxRef: ForwardedRef<HTMLButtonElement>;
}) => (
  <Checkbox
    {...props}
    ref={checkboxRef}
    sx={{
      color: "#363636",
      "&.Mui-checked": {
        color: "#363636"
      }
    }}
  />
);

const ForwardCustomCheckbox = forwardRef<HTMLButtonElement, CheckboxProps>((props, ref) => {
  return <CustomCheckbox {...props} checkboxRef={ref} />;
});
关于as类型断言的使用边界

你抵触用as绕过类型检查的思路是正确的,日常开发中优先通过补全泛型、修正类型定义解决类型报错,是比直接断言更稳妥的做法。
这类类型断言仅在以下场景属于可接受的写法:

  • 你100%确认值的运行时类型和断言类型一致,类型报错来自上游第三方库的类型定义缺陷,且短时间无法推动上游修复
  • 断言的范围尽可能窄,不要直接大范围断言为any/unknown,只针对确定类型的最小粒度值做断言
  • 必要时补充单行注释说明断言原因,方便后续维护

你当前场景的类型报错完全来自自身代码的类型标注错误,不属于上游缺陷,因此没有使用类型断言的必要,直接按上述方案修正类型定义即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:21:37