I have this (simplified) component:
export type BaseProps = {
size?: 'xs' | 'sm' | 'md' | 'lg';
}
type ButtonAsButtonProps = Omit<React.ComponentPropsWithoutRef<'button'>, 'as'> & BaseProps & {
as?: 'button';
}
type ButtonAsLinkProps = Omit<React.ComponentPropsWithoutRef<'a'>, 'as'> & BaseProps & {
as: 'link';
link: string;
}
type ButtonProps = ButtonAsButtonProps | ButtonAsLinkProps
const Button = ( props : ButtonProps ) => {
props.as = props.as ?? 'button'
if ( props.as === 'link' ) {
return <Link { ... props } />
}
return <Box<'button'> as='button' { ... props } />
}
export default Button
These scenarios work as expected:
// Typescript complains about link not being part of props (as expected)
<Button as='button' link='' disabled />
// Typescript complains about 'disabled' not being part of props (as expected)
<Button as='link' link='' disabled />
The problem is when I do this:
// Typescript complains about none of these props
<Button link='' href='' target='' onClick={} disabled />
In this case, I would expect Typescript to use the ButtonAsButtonProps
since ‘button’ is the default value for the ‘as’ prop and complain about link, href and target, but it doesn’t; and it doesn’t complain about onClick or disabled either, it’s as if it’s merging ButtonAsButtonProps
as ButtonAsLinkProps
. I’ve checked other similar questions and they seemed to resolve by not destructuring props, but I’ve tried that (as you can see from the component code) and it didn’t fix my issue. Don’t really know what to do.