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

TypeScript中如何判断传入的React图标是CustomIcon还是MUI图标?

解决方案

首先,React元素的type属性可以直接用来区分不同组件生成的元素——当你传入<CustomIcon />时,这个元素的type就是CustomIcon组件本身;而MUI图标元素的type是对应的MUI组件(比如HomeIcon)。利用这一点就能实现条件判断,再通过cloneElement给图标添加额外属性。

基础实现(仅传入React元素的情况)

假设你的ParentComponentProps只接收渲染好的React元素(和你给出的调用示例一致),可以这样处理:

import { ReactElement, cloneElement } from 'react';
import { SvgIconProps } from '@mui/material/SvgIcon';

// 自定义CustomIcon的props类型
type CustomIconProps = {
  className?: string;
  // 你的其他自定义属性
};

type ParentComponentProps = {
  icon: ReactElement<SvgIconProps> | ReactElement<CustomIconProps>;
};

const ParentComponent = ({ icon }: ParentComponentProps) => {
  // 判断当前元素是否为CustomIcon生成
  const isCustomIcon = icon.type === CustomIcon;

  // 根据类型添加不同的额外属性
  const extraProps = isCustomIcon 
    ? { className: `${icon.props.className || ''} custom-icon-extra-class` }
    : { className: `${icon.props.className || ''} mui-icon-extra-class` };

  // 克隆原图标元素并合并属性
  const enhancedIcon = cloneElement(icon, extraProps);

  return <div>{enhancedIcon}</div>;
};

兼容传入组件类型的情况

如果你的ParentComponentProps确实允许传入CustomIcon组件本身(而非渲染后的元素),需要先区分传入的是组件还是React元素:

import { ReactElement, cloneElement, isValidElement } from 'react';
import { SvgIconProps } from '@mui/material/SvgIcon';

type ParentComponentProps = {
  icon: ReactElement<SvgIconProps> | typeof CustomIcon;
};

const ParentComponent = ({ icon }: ParentComponentProps) => {
  let enhancedIcon;

  if (isValidElement(icon)) {
    // 处理传入的React元素
    const isCustomIcon = icon.type === CustomIcon;
    const extraProps = isCustomIcon
      ? { className: 'custom-icon-extra' }
      : { className: 'mui-icon-extra' };
    enhancedIcon = cloneElement(icon, extraProps);
  } else {
    // 处理传入的CustomIcon组件本身,直接渲染并附加属性
    enhancedIcon = <icon className="custom-component-extra" />;
  }

  return <div>{enhancedIcon}</div>;
};

应对组件被高阶组件包装的情况

如果CustomIcon被memo等高阶组件包装过,直接判断icon.type === CustomIcon会失效,这时候可以给CustomIcon添加一个唯一标识来做判断:

// 给CustomIcon添加自定义标识
const CustomIcon = (props: CustomIconProps) => {
  // ...组件实现
};
CustomIcon.isCustomComponent = true;

// 在ParentComponent中判断
const isCustomIcon = typeof icon.type === 'function' && (icon.type as any).isCustomComponent;

为什么typeof/instanceof不适用?

  • typeof只能判断出组件是函数类型,但MUI图标和你的CustomIcon都是函数组件,无法区分;
  • instanceof仅适用于类组件,对函数组件无效;
  • TypeScript的类型是编译时信息,运行时无法直接通过类型做判断,必须依赖运行时可访问的标识或属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 14:05:23