0
What’s going on
I have a button component with its dynamic html tag [a, button], but the way I called it shows error in some props like the onClick
, anchor who receives an event of type click on anchor
and on the button an event of the type click on button
.
I wanted to know a way to define what exactly the button receives from props and not concatenate as I did there and occur these errors.
Typing that seems to be wrong
On the operator &
I’ve tried to trade for |
, but there are other mistakes.
FC<Props & (
AnchorHTMLAttributes<HTMLAnchorElement>
& ButtonHTMLAttributes<HTMLButtonElement>
)>
The component
import React, {
AnchorHTMLAttributes,
ButtonHTMLAttributes,
FC,
HTMLProps,
ReactElement
} from 'react';
const htmlTags = {
a: 'a',
button: 'button',
} as const;
type HTMLTag = keyof typeof htmlTags;
interface Props {
tag: HTMLTag;
}
const tags = {
a: (props: AnchorHTMLAttributes<HTMLAnchorElement>): ReactElement => <a {...props} />,
button: (props: ButtonHTMLAttributes<HTMLButtonElement>): ReactElement => <button {...props} />,
};
const Button: FC<Props & (
& AnchorHTMLAttributes<HTMLAnchorElement>
& ButtonHTMLAttributes<HTMLButtonElement>
)> = ({
children,
tag = 'button',
...props
}) => {
const Tag = tags[tag];
const isAnchorTag = tag === 'a';
const isButtonTag = tag === 'button';
const restProps = { ...props };
if (isAnchorTag) {
delete restProps.href;
}
if (isButtonTag) {
restProps.type = restProps.type ?? 'button';
} else {
delete restProps.type;
}
return (
<Tag {...restProps}>
{children}
</Tag>
);
};
The call of the component
function handleClickToCopyBarcode(): void {
// ...
}
<Button onClick={handleClickToCopyBarcode} className={classes} {...props}>
teste
</Button>
Error
Type '((event: MouseEvent<HTMLButtonElement, MouseEvent>) => void) | (() => void)' is not assignable to type '((event: MouseEvent<HTMLAnchorElement, MouseEvent>) => void) & ((event: MouseEvent<HTMLButtonElement, MouseEvent>) => void)'.
Edit your question to include the type that function
handleClickToCopyBarcode
assumes. Implementation is not so important in this case, but may also include...– Luiz Felipe
I edited the question and put how I declared the function
handleClickToCopyBarcode
.– Jomar Antônio Cardoso
putting a any works? replace the 2 with a any, or create a manual interface that you mix the 2, I believe you can use the spreed Operator to create this mixed interface
– Joannis
@Joannis, the problem is, when using the
any
, loses one of the main benefits that Typescript brings, that is, security.– Luiz Felipe
I would like this to be solved in the button component, because this problem can be repeated in several other attributes: onFocus, onBlur, onHover... In addition to requiring that each one who uses it needs to think about how to solve it.
– Jomar Antônio Cardoso