I use React 16 and Typescript 3. I create a component that returns button or link based on whether property to is set or not. The component may get either to or onClick property, it can't take both.
I found issue on TypeScript repository which exactly describes my problem and it seems fixed in 2.2 version, but in some strange way, it doesn't work.
For that purpose I created interfaces and use them as follows:
interface GeneralProps {/* whatever here, it works */}
interface LinkProps extends GeneralProps { to: string }
interface ButtonProps extends GeneralProps {
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void
// onClick might be as well undefined
}
function Button (props: LinkProps | ButtonProps): JSX.Element {
const Component: AnyStyledComponent = props.to ? Link : Button
return (
<Component to={props.to} onClick={props.onClick}>
{props.children}
</Component>
)
}
Alternatively, I also tried to write this function like this:
function Button (props: LinkProps): JSX.Element
function Button (props: ButtonProps): JSX.Element {
const Component: AnyStyledComponent = props.to ? Link : Button
return (
<Component to={props.to} onClick={props.onClick}>
{props.children}
</Component>
)
}
The first implementation of the Button function above throws both errors, the second one throws only the first one:
Property 'to' does not exist on type 'LinkProps | ButtonProps'. Property 'to' does not exist on type 'ButtonProps'.
Property 'onClick' does not exist on type 'LinkProps | ButtonProps'. Property 'onClick' does not exist on type 'LinkProps'.
To avoid errors, I came with the silly workaround:
function Button (props: LinkProps | ButtonProps): JSX.Element {
const properties = Object.keys(props)
const to = properties.find((el) => el === 'to')
const Component: AnyStyledComponent = to ? Link : Button
return (
<Component {...props}>
{props.children}
</Component>
)
}
However, that doesn't solve my problem, because I still can pass both to and onClick property to the Button component.
Do I have some kind of an error in my code that prevents me from achieving my goal, should I approach this problem from a different angle or is this plain impossible to do?