I'm trying to create a button component that can be an anchor tag with a href or a button tag with a type prop. I have the following code:
interface IBaseProps {
children: string;
fullSize?: boolean;
theme?: 'primary' | 'secondary' | 'dark';
}
interface ILinkButtonProps extends IBaseProps {
url: string;
type: never;
props?: AnchorHTMLAttributes<HTMLAnchorElement>;
}
interface IButtonProps extends IBaseProps {
type: 'button' | 'submit' | 'reset';
url: never;
props?: ButtonHTMLAttributes<HTMLButtonElement>;
}
export const Button = ({
children,
props,
theme = 'primary',
fullSize = false,
type = 'button',
url,
}: IButtonProps | ILinkButtonProps): JSX.Element => {
const Tag: keyof JSX.IntrinsicElements = url ? 'button' : 'a';
return (
<Tag
className={`${styles.button} ${styles[theme]} ${
fullSize ? styles.fullSize : ''
}`} // not important
{...props}
{...(Tag === "button" ? {type: `${type}`} : {href: url})}
>
{children}
</Tag>
);
};
However, that gives me some typing errors, for instance:
Types of property 'onCopy' are incompatible. Type 'ClipboardEventHandler | undefined' is not assignable to type 'ClipboardEventHandler | undefined'. Type 'ClipboardEventHandler' is not assignable to type 'ClipboardEventHandler'. Type 'HTMLAnchorElement' is missing the following properties from type 'HTMLButtonElement': disabled, form, formAction, formEnctype, and 11 more.
Is there a way for me to format my code with typescript, so I can achieve a component that allows me to have both a button or a link?