For a button link component, I'm trying to choose between HTMLButtonAttributes or HTMLAnchorAttributes based on passed props. My knowledge of TypeScript is quite limited.
I have the following types and interfaces:
interface CommonButtonProps {
// custom props
}
export interface ButtonProps extends CommonButtonProps,
React.ButtonHTMLAttributes<HTMLButtonElement> {}
export interface ButtonLinkProps extends CommonButtonProps,
React.AnchorHTMLAttributes<HTMLAnchorElement> {
href: string;
}
export type ButtonOrButtonLinkProps = ButtonProps | ButtonLinkProps;
export const isButtonLink = (props: ButtonOrButtonLinkProps,): props is ButtonLinkProps => guard logic
And the following Button component with ButtonOrButtonLinkProps:
export const Button: React.FC<ButtonOrButtonLinkProps> = props => {
const buttonLink = isButtonLink(props);
const commonProps = {
};
const linkProps: ButtonLinkProps = {
...commonProps,
onClick: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
// Do stuff
if (props.onClick) {
props.onClick(event); // Error
}
},
};
const buttonProps: ButtonProps = {
...commonProps,
type: 'button',
onClick: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
// Do other stuff
if (props.onClick) {
props.onClick(event); // Error
}
},
};
return (
<StyledBtn {...(buttonLink ? linkProps : buttonProps)}>
{children}
</StyledBtn>
);
};
The following line throws an error:
if (props.onClick) {
props.onClick(event); // Error
}
Argument of type 'MouseEvent<HTMLButtonElement, MouseEvent>' is not assignable to parameter of type 'MouseEvent<HTMLButtonElement, MouseEvent> & MouseEvent<HTMLAnchorElement, MouseEvent>'. Type 'MouseEvent<HTMLButtonElement, MouseEvent>' is not assignable to type 'MouseEvent<HTMLAnchorElement, MouseEvent>'. Type 'HTMLButtonElement' is missing the following properties from type 'HTMLAnchorElement': charset, coords, download, hreflang, and 19 more.
It seems the current type of onClick
is
Why is the event type and intersection of MouseEvent of HTMLButtonElement &
MouseEvent of HTMLAnchorElement ? I kinda expected it to be an union - either one or the other ?
Any idea how to fix the issue ?