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

如何无需显式声明,让TextButton继承ButtonProps的所有属性?

问题描述

现有Button组件及对应的ButtonProps接口如下:

interface ButtonProps {
    children?: React.ReactNode,
    backgroundColor?: Colors,
    style?: object,
    disabled?: boolean,
    classes?: string
    onClick?: () => void
}


const Button = ({
                        backgroundColor,
                        classes,
                        children,
                        disabled = false,
                        onClick,
                        style,
                    }: ButtonProps) => {

    const _constructInlineStyles = (): CSSProperties => {
        ...
    }

    return (
        <button
            className={clsx(classes, 'button-container')}
            disabled={disabled}
            onClick={onClick}
            style={...}>
                {children}
        </button>
    )
}

export default Button;

基于该Button封装TextButton的初始实现为:

interface TextButtonProps {
    children: string;
}

const TextButton = ({
                        children,
                    }: TextButtonProps) => {
    return (
        <Button>
            <Text>
                {children}
            </Text>
        </Button>
    )
}

export default TextButton;

需求是无需显式列出ButtonProps的每个属性,让TextButton支持ButtonProps的所有属性,不想采用这种逐个声明属性的繁琐写法:

interface TextButtonProps {
    children: string;
}

const TextButton = ({
                        children,
                        backgroundColor,
                        classes,
                        disabled = false,
                        onClick,
                        style,
                    }: TextButtonProps & ButtonProps ) => {
    return (
        <Button
             className={classes}
             disabled={disabled}
             onClick={onClick}
             style={style}>
            <Text>
                {children}
            </Text>
        </Button>
    )
}

想问是否可以用类似下面的写法,让TextButton直接接收ButtonProps的属性(比如直接写<TextButton disabled={true}>Fooo</TextButton>):

interface TextButtonProps {
    children: string;
    props: ButtonProps;
}

const TextButton = ({
                        children,
                        props,
                    }: TextButtonProps) => {
    return (
        <Button
             {...props}>
            <Text>
                {children}
            </Text>
        </Button>
    )
}

解决方案

你提到的写法无法实现<TextButton disabled={true}>Fooo</TextButton>这种直接传参的效果——这种写法要求必须把Button的所有属性都嵌套在props对象里使用,比如得写成:

<TextButton props={{ disabled: true }}>Fooo</TextButton>

这显然不符合你的需求。

正确的实现方式是让TextButtonProps继承ButtonProps,同时覆盖children的类型(因为你需要TextButton的children是string,而Button的是ReactNode),再通过剩余属性语法接收所有ButtonProps的其他属性,最后用展开运算符传给Button组件。

具体代码如下:

// 继承ButtonProps并覆盖children的类型约束
interface TextButtonProps extends ButtonProps {
    children: string;
}

const TextButton = ({
                        children,
                        ...restProps // 接收除children外的所有ButtonProps属性
                    }: TextButtonProps) => {
    return (
        <Button {...restProps}> {/* 把所有继承来的属性展开传给Button */}
            <Text>{children}</Text>
        </Button>
    )
}

export default TextButton;

这种写法的优势:

  • 无需逐个声明ButtonProps的属性,自动继承所有属性
  • 直接支持<TextButton disabled={true} backgroundColor="red">Fooo</TextButton>这种直观写法
  • 保留了TextButton对children的类型约束(必须为string)
  • 维护性高:后续ButtonProps新增属性时,TextButton会自动支持,无需额外修改

内容的提问来源于stack exchange,提问作者four-eyes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 08:15:35