Reputation: 4824
Is it possible to restrict passing a valid prop to a react component?
Example:
<SomeComponent primaryCTA={<Button size="small">Click here</Button} />
Now, in the code above, I want to user to NOT be able to provide size prop.
This is how type Props of SomeComponent look like
type SomeComponentProps = {
primaryCTA: React.ReactElement<
Exclude<ButtonProps, 'size'>,
typeof Button>;
}
But, the code above doesn't work. You can still provide size prop to Button component inside SomeComponent.
Upvotes: 1
Views: 750
Reputation: 187024
You can't restrict the type here because rendered JSX doesn't carry with it the type of the component that rendered it. This means that there is no type information to restrict:
const button = <Button size="small">foo</Button> // type: JSX.Element
Instead, it's usually best to let SomeComponent
handle creating the button by exposing props about how to do that.
For example, if primaryCTA
was typed as string
, then in your SomeComponent
rendering you could create the button:
function SomeComponent({ primaryCTA }: Props) {
return <Button size="small-or-whatever">{primaryCTA}</Button>
}
Or you can make primaryCTA
be the type of props that Button
expects.
You can use React.ComponentProps<typeof Button>
to get the prop types from the Button
component, and then you can use Omit<Props, 'size'>
to remove whatever you don't want to expose. Lastly, you can spread those props back into the button with <Button {...primaryCTA} />
Putting that together, you could do something like:
interface SomeComponentProps {
primaryCTA: Omit<React.ComponentProps<typeof Button>, 'size'>
}
function SomeComponent({ primaryCTA }: SomeComponentProps) {
return <>
<div>Testing this component</div>
<Button {...primaryCTA} size='small' />
</>
}
// Usage of SomeComponent
<SomeComponent primaryCTA={{ color: 'red', children: 'click here!' }} />
Upvotes: 1