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

Material-UI Button的component属性如何推断传入组件Props?如何实现同款能力?

MUI 可替换组件类型推断的实现原理

这种能力的核心是 TypeScript 泛型 + 内置的React.ComponentProps类型工具:

  • 组件的Props定义为泛型,泛型参数对应传入的component类型
  • 用React.ComponentProps<T>自动提取传入组件的所有Props类型
  • 将组件自身的固定Props和传入组件的Props做交叉,就得到了最终支持的所有属性类型

MyImage 组件的实现代码

你可以直接参考下面的模板实现你的需求:

import React from 'react';

// 先定义MyImage自身独有的Props
interface MyImageBaseProps {
  // 示例自定义属性,可根据你的需求修改
  roundCorner?: boolean;
  customCaption?: string;
}

// 定义泛型Props,T是传入的component类型,默认是img标签
type MyImageProps<T extends React.ElementType = 'img'> = 
  MyImageBaseProps & 
  {
    component?: T;
  } & 
  // 排除和自身重复的属性,避免类型冲突
  Omit<React.ComponentProps<T>, keyof MyImageBaseProps>;

// 组件本身也要声明为泛型组件
const MyImage = <T extends React.ElementType = 'img'>({
  component,
  roundCorner,
  customCaption,
  ...restProps
}: MyImageProps<T>) => {
  // 动态渲染根组件,没传component默认用img
  const Component = component || 'img';

  // 你的自定义逻辑,比如样式处理
  const computedStyle = {
    ...(roundCorner ? { borderRadius: '8px' } : {}),
  };

  return (
    <div>
      <Component style={computedStyle} {...restProps} />
      {customCaption && <p>{customCaption}</p>}
    </div>
  );
};

export default MyImage;

使用示例

// 用默认img标签,支持原生img的所有属性
<MyImage src="xxx.png" alt="测试图" roundCorner />

// 传入Next.js的Image组件,自动支持NextImage的所有属性
import NextImage from 'next/image';
<MyImage component={NextImage} src="xxx.png" alt="测试图" width={200} height={200} fill />

注:如果传入的自定义组件有必传属性,TS会自动做校验,和直接使用目标组件的类型提示完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 12:15:03