如何使用样式组件扩展(MUI)React 组件的 TS 接口?
Posted
技术标签:
【中文标题】如何使用样式组件扩展(MUI)React 组件的 TS 接口?【英文标题】:How to extend TS interface for (MUI) React Component using styled-components? 【发布时间】:2021-09-19 06:19:42 【问题描述】:我一直在试图弄清楚如何解决这个过载问题,但到目前为止还没有骰子。我正在使用 Typescript、Styled-components 和 material-ui。我正在使用 styled(MUIButton)
构建原生 MUI Button
。通过 console.logs 我可以看到我的 props 传递到组件中,但是我不知道如何设置类型,所以重载错误消失了。
有什么想法吗?
相关文章:How to extend props for Material-UI components using Typescript?
错误:
代码:
import default as MUIButton, ButtonProps from '@material-ui/core/Button';
import styled, css from 'styled-components';
import darken from '@material-ui/core/styles';
interface IButton extends ButtonProps
format?: 'primary' | 'secondary';
variant?: 'contained' | 'outlined' | 'text';
label: string;
const Button = ( format, variant, label : IButton): JSX.Element => (
<StyledButton format=format variant=variant>
label
</StyledButton>
);
Button.defaultProps =
format: 'primary',
variant: 'contained',
;
export default Button;
const StyledButton = styled(MUIButton)<IButton>`
//? contained variant (default)
$( format, theme ) => `
background-color: $
format === 'primary'
? theme.palette.colors.main
: theme.palette.colors.secondary
;
color: $theme.palette.font.secondary;
font-weight: $theme.agnosticStyles.font.weight.bold;
padding: .7rem 4rem;
&:hover
background-color: $darken(theme.palette.colors.main, 0.2);
`
...
【问题讨论】:
请提供包的版本 它是一个新项目,所以它的所有最新版本 它在 ts playground 中抛出错误 【参考方案1】:这是因为format
是一个自定义属性,您需要将其作为参数传递给StyleButton
元素。
由于您已经创建了IButton
接口,您可以像这样使用它:
const StyledButton = styled(MUIButton)<IButton>`
$props => console.log(props)
...
`;
使用上面的代码,您还需要将界面中的label
设置为可为空(如果不这样做,您将收到错误Property 'label' is missing in type
):
interface IButton extends ButtonProps
format?: "primary" | "secondary";
variant?: "contained" | "outlined" | "text";
label?: string;
const Button = ( format, variant, label : IButton): JSX.Element => (
<StyledButton format=format variant=variant>
label
</StyledButton>
);
<Button label="test" format="primary" variant="contained" />
另一种方法是将您的 Button 设置为 FunctionComponnent
,然后,您将不再需要 label
属性,您可以改用 children
:
interface IButton extends ButtonProps
format?: "primary" | "secondary";
variant?: "contained" | "outlined" | "text";
const StyledButton = styled(MUIButton)<IButton>`
...
`;
const Button: React.FC<IButton> = ( format, variant, children ) => (
<StyledButton format=format variant=variant>
children
</StyledButton>
);
<Button format="secondary" variant="text">
Test
</Button>
您可以在 styled-components here 中查看有关自定义道具的更多信息
更新
如果将<StyledButton>
中的format
替换为color
,就会得到想要的按钮样式。
interface IButton extends ButtonProps
format?: "primary" | "secondary";
variant?: "contained" | "outlined" | "text";
const StyledButton = styled(MUIButton)<IButton>`
...
`;
const Button: React.FC<IButton> = ( format, variant, children ) => (
// ******
// HERE'S THE TRICK -> INSTEAD FORMAT, YOU SHOULD SET COLOR
// ******
<StyledButton color=format variant=variant>
children
</StyledButton>
);
<Button variant="contained" format="primary">
primary
</Button>
<Button variant="outlined" format="secondary">
secondary
</Button>
【讨论】:
嗨 Luis,感谢您的详尽回答。我更新了我的 styled-component 部分,使其具有<IButton>
类型。但是,我正在构建的底层材料-ui <Button>
没有 format
属性。我很好奇如何将新的 format
属性附加到现有按钮以解决 TS 错误。
当您说格式时,您是指样式颜色按钮吗?您只需将format
替换为color
即可完成此操作。我将在答案中包含一个示例。
再次感谢您的反馈,在这种情况下,我实际上指的是向按钮添加一个名为“格式”的 new 属性。 format
有两个值:primary 或 secondary,它用于确定将在 styled-components 中实现的多种样式。 format
本身并不存在于 MUI 按钮上,因为我刚刚创建了它。最初帖子中的屏幕截图显示了唯一出现的错误,我相信这是打字稿说“嘿,按钮上不存在格式”。我不知道如何在按钮上输入以解决 TS 投诉
我在最初的帖子中添加了更多内容,展示了“格式”属性的样式化组件意图以及它如何用于通过三元组应用样式(在本例中)。
对不起,我好像在用 cmets 轰炸你。不过,我想我已经解决了。我应用了您的children
方法,错误都消失了。因此,在进一步探索了这个错误之后,我想我是在追逐一条红鲱鱼。该问题与我的label
有关,如果我将其设为条件并提供似乎也可以使用的默认值。 Property 'label' is missing in type ' children: string; color?: "inherit" | "primary" | "secondary" | "default"; disabled?: boolean; disableElevation?: ...
是出现的错误。我不确定它为什么会出现。标签在IButton
【参考方案2】:
您的StyledButton
组件的外观并不完全清楚。来自@material-ui/core
的原始Button
不接受format
属性。这正是这个错误的原因。
如果您在 StyledButton
中以某种方式使用此属性,您应该相应地键入它:
const StyledButton = styled(MUIButton)<format?: 'primary' | 'secondary'>``;
尽管您可能正在寻找 color
属性,原始 Button
接受并且可能同时接受 primary
和 secondary
值。
【讨论】:
没错,它没有format
属性。我基本上想将该属性附加到已经存在的材料 ui Button
以上是关于如何使用样式组件扩展(MUI)React 组件的 TS 接口?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 React MUI 覆盖 TextField 组件的宽度?
如何使用来自@mui/material 的样式使情感组件选择器在 nextjs 应用程序中工作?