I’m working on a React component with TypeScript and I’m trying to create a flexible, yet type-safe prop interface. However, I’m concerned that my current implementation might be too permissive. Here’s my type definition:
type CustomComponentPropsBase<Component extends ElementType> = {
size?: Size;
} & ComponentPropsWithoutRef<Component>;
type CustomComponentPropsWithoutChildren = {
asChild?: false;
children?: never;
};
type CustomComponentPropsWithChildren = {
asChild: true;
children: ReactElement;
};
type CustomComponentProps<Component extends ElementType> = CustomComponentPropsBase<Component> &
(CustomComponentPropsWithoutChildren | CustomComponentPropsWithChildren);
export default function CustomComponent<Component extends ElementType = "div">({
size = "default",
asChild = false,
children,
...props
}: CustomComponentProps<Component>): JSX.Element {
// Component implementation
}
My intention was to create a component that:
- Can be rendered as different HTML elements or React components
- Has a size prop
- Either doesn’t allow children (asChild: false) or requires a single child element (asChild: true)
- Allows all props of the underlying component (via ComponentPropsWithoutRef), including the default “div” if no children is passed
However, I’m worried that this type definition might be too permissive and allow any property to be passed to the component, weakening the type safety as I can just access props.whatever
without raising any type issue.
1