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
handleClickToCopyBarcodeassumes. 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