Reputation: 716
I have a component that can accept another component as a prop. Whatever other props it has, it also passes them down to the child component. That's what it looks like:
interface FormGroupProps extends BasicInputProps<any> {
label: string
name: string
Component: ComponentType<BasicInputProps<any>>
}
export const FormGroup: SFC<FormGroupProps> = ({
label,
Component,
...props
}) => (
<RBSFormGroup>
<Label>{label}</Label>
<Component {...props} />
</RBSFormGroup>
)
You can see that in FormGroupProps
I tell TS that Component will accept only props of a certain type. That is not ideal, because sometimes I need to pass components that don't necessarily match that signature.
I could potentially just write ComponentType<any>
, but that's too loose. I'd like to be able to write something like ComponentType<Component['props']>
, but as far as I know there's no such thing.
Is there a way to reference a components props type? Or do I need to pass a generic type manually to achieve that?
Upvotes: 3
Views: 6529
Reputation: 1127
New typings introduced to @types/react
in response to React 16.6 include the following types:
type ComponentProps<T extends keyof JSX.IntrinsicElements | JSXElementConstructor<any>> =
T extends JSXElementConstructor<infer P>
? P
: T extends keyof JSX.IntrinsicElements
? JSX.IntrinsicElements[T]
: {};
type ComponentPropsWithRef<T extends ElementType> =
T extends ComponentClass<infer P>
? PropsWithoutRef<P> & RefAttributes<InstanceType<T>>
: PropsWithRef<ComponentProps<T>>;
type ComponentPropsWithoutRef<T extends ElementType> = PropsWithoutRef<ComponentProps<T>>;
Which reference the types of a component's props. You should be able to achieve your desired interface using one of these new types:
interface FormGroupProps {
label: string;
name: string;
Component: React.ComponentProps<typeof Component>;
}
This is super handy if you want to avoid exporting prop interfaces all over the place, or for extracting props interfaces from libraries which don't export them. Also, unlike Component['props']
, it also works for functional components.
Upvotes: 3