Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface cannot simultaneously extend types anchor and button

I have the following interface for a React button (that can be an anchor or button):

type ButtonTypes = HTMLAnchorElement | HTMLButtonElement;

interface ButtonProps<T extends ButtonTypes>
    extends React.AnchorHTMLAttributes<T>, React.ButtonHTMLAttributes<T> {
    className?: string;
    kind: 'default' | 'primary' | 'secondary' | 'tertiary';
    disabled?: boolean;
    icon?: React.ReactElement<React.HTMLProps<HTMLOrSVGElement>>;
    trailingIcon?: boolean;
    iconOnly?: boolean;
    fullWidth?: boolean;
    outline?: boolean;
    size?: 'small' | 'large';
    href?: string;
    children?: React.ReactNode;
}

But I'm getting the error that I can't extend both React.AnchorHTMLAttributes<T> and React.ButtonHTMLAttributes<T> due to named property 'type' of types are not identical...

However this is inspired by how Material Design have built their button: https://github.com/material-components/material-components-web-react/blob/master/packages/button/index.tsx#L38

So not sure why I can't inherit from both but they (MDC) have been able to? Am I missing something (syntax or type package) to allow this behaviour?

like image 761
Ian Avatar asked Mar 10 '26 11:03

Ian


1 Answers

To fix this I had to overwrite the type property by adding:

type?: 'submit' | 'reset' | 'button'; into my ButtonProps interface.

I also had to change how my buttons were built from:

if (href) {
    return (
        <a {...(props as React.HTMLProps<HTMLAnchorElement>)} href={href}>{btnContent}</a>
    )
}

return (
    <button {...(props as React.HTMLProps<HTMLButtonElement>)}>{btnContent}</button>
);

to:

if (href) {
    return (
        <a {...(props as React.AnchorHTMLAttributes<HTMLAnchorElement>)} href={href}>{btnContent}</a>
    )
}

return (
    <button {...(props as React.ButtonHTMLAttributes<HTMLButtonElement>)}>{btnContent}</button>
);
like image 141
Ian Avatar answered Mar 13 '26 02:03

Ian