I have this Button component
// React
import React from 'react'
interface ButtonProps = {
onAction?: () => void
onDoubleAction?: () => void
}
const Button: React.FC<ButtonProps> = ({
onAction,
onDoubleAction
}: ButtonProps) => {
// Event 'click' on button
const handleClick = () => {
// Call 'onAction' or 'onDoubleAction'
}
return (
<button type="button" onClick={handleClick}>
button example
</button>
)
}
export default Button
My problem is when I invoke the button, for example
<div>
<Button onAction={onAction} onDoubleAction={onDoubleAction} />
</div>
I would like that, if exists 'onAction' and 'onDoubleAction' props, typescript show error 'You can use only onAction or onDoubleAction but do not both' . I want that the button only can receive 'onclick' event or 'doubleclick' event, but if receive both events, typescript returns an error to make it known that only one of the two can be used
For example
<div>
<Button onAction={onAction} /> // Good
</div>
<div>
<Button onDoubleAction={onAction} /> // Good
</div>
<div>
<Button onAction={onAction} onDoubleAction={onAction} /> // Error in component
</div>
Thanks!!
CodePudding user response:
You can do this with union types!
type onAction = { onAction: () => void; onDoubleAction?: never };
type onDoubleAction = { onAction?: never; onDoubleAction: () => void };
type ButtonProps = onAction | onDoubleAction;
export const UnionButton: React.FC<ButtonProps> = (t) => {
const handleClick = () => {
// Call 'onAction' or 'onDoubleAction'
const key = Object.keys(t)[0] as keyof typeof t;
const func = t[key] as () => void;
func();
};
return (
<button type="button" onClick={handleClick}>
button example
</button>
);
};
const SomeButtons = () => {
return (
<>
<UnionButton onAction={() => console.log("single")} /> //happy
<UnionButton onDoubleAction={() => console.log("double")} /> //happy
<UnionButton //sad
onAction={() => console.log("single")}
onDoubleAction={() => console.log("i will create type error")}
/>
</>
);
};