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

带参数的Styled Base UI组件触发TypeScript错误,需何种类型修改修复?

修复Emotion styled MUI BaseButton的TypeScript类型错误

原始TSX代码

import React from "react";
import BaseButton from "@mui/base/Button";
import styled from "@emotion/styled";

export const enum BUTTON_TYPE {
  MAIN = "main",
  LINK = "link",
}

const Button = ({
  text,
  type,
}: {
  text: string;
  type: BUTTON_TYPE;
}) => {
  return (
    <StyledButton type={type}>
      {text}
    </StyledButton>
  );
};

const getBorderColor = (type: BUTTON_TYPE): string => {
  if(type === BUTTON_TYPE.MAIN) {
    return "#abcabc";
  }
  else {
    return "#cbacba";
  }
};

const StyledButton = styled(BaseButton)<{
  type: BUTTON_TYPE;
}>`
  border: 1px solid ${({ type }) => getBorderColor(type)};
`;

export default Button;

触发的TypeScript错误

src/modules/Button/Button.tsx:18:6 - error TS2745: This JSX tag's 'children' prop 
expects type 'never' which requires multiple children, but only a single child was 
provided.

18     <StyledButton type={type}>
    ~~~~~~~~~~~~

src/modules/Button/Button.tsx:18:19 - error TS2322: Type 
'import("C:/ez/DS13/src/modules/Button/Button2").BUTTON_TYPE' is not assignable to type 
'never'.

18     <StyledButton type={type}>

修复方案

错误根源是自定义styled组件时,没有把BaseButton自带的Props类型和自定义的type属性类型合并,导致TypeScript丢失了组件原生的children、按钮属性等类型信息,同时无法识别你传入的type属性。

步骤1:导入BaseButton的原生Props类型

先从MUI的BaseButton里导入它原本的Props类型:

import type { ButtonProps } from '@mui/base/Button';

步骤2:合并类型定义

定义StyledButton时,把自定义的type属性和ButtonProps交叉合并,确保保留原生组件的所有类型:

const StyledButton = styled(BaseButton)<ButtonProps & { type: BUTTON_TYPE }>`
  border: 1px solid ${({ type }) => getBorderColor(type)};
`;

(可选)避免自定义属性传到DOM元素

如果不想让自定义的type属性被传递到底层的<button>DOM标签上,可以加个过滤规则:

const StyledButton = styled(BaseButton, {
  // 只传递除了type之外的属性给原生按钮
  shouldForwardProp: (prop) => prop !== 'type'
})<ButtonProps & { type: BUTTON_TYPE }>`
  border: 1px solid ${({ type }) => getBorderColor(type)};
`;

完整修复后的代码

import React from "react";
import BaseButton from "@mui/base/Button";
import type { ButtonProps } from '@mui/base/Button';
import styled from "@emotion/styled";

export const enum BUTTON_TYPE {
  MAIN = "main",
  LINK = "link",
}

const Button = ({
  text,
  type,
}: {
  text: string;
  type: BUTTON_TYPE;
}) => {
  return (
    <StyledButton type={type}>
      {text}
    </StyledButton>
  );
};

const getBorderColor = (type: BUTTON_TYPE): string => {
  if(type === BUTTON_TYPE.MAIN) {
    return "#abcabc";
  }
  else {
    return "#cbacba";
  }
};

const StyledButton = styled(BaseButton, {
  shouldForwardProp: (prop) => prop !== 'type'
})<ButtonProps & { type: BUTTON_TYPE }>`
  border: 1px solid ${({ type }) => getBorderColor(type)};
`;

export default Button;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 01:17:42