[React Typescript] ElementType, ComponentType
The ElementType
type helper is a bit unusal because it accepts some props and derives what types of components would be able to recieve those props.
Here we have an Example
component that accepts audio
and video
as well as ComponentType<P>
.
When we pass it an autoPlay
prop:
export type Example = React.ElementType<{
autoPlay?: boolean;
}>;
// hovering over Example shows:
type Example =
| "audio"
| "video"
| React.ComponentType<{
autoPlay?: boolean | undefined;
}>;
ElementType
can tell that this prop can be used with an audio
or video
element, or a React Component Type that accepts autoPlay
as a prop.
Any custom component that you think of will correspond to ElementType
, as well as any other element defined in JSX.IntrinsicElements
that can receive props.
For example, many elements can accept an href
prop. If you defined an ElementType
to accept an optional href
, all of a sudden there are several possible elements that can be used:
type Example = React.ElementType<{
href?: string;
}>;
// hovering over Example shows:
type Example = "symbol" | "a" | "area" | "base" | "link" |
"svg" | "animate" | "animateMotion" | "animateTransform" |
"circle" | "clipPath" | "defs" | "desc" | "ellipse" |
"feBlend" | "feColorMatrix" | ... 46 more ...
| React.ComponentType<...>
ComponentType
Here we have a FuncComponent
and a ClassComponent
that take a prop1
that is a string:
const FuncComponent = (props: { prop1: string }) => {
return null;
};
class ClassComponent extends React.Component<{
prop1: string;
}> {
render(): React.ReactNode {
this.props.prop1;
return null;
}
}
By using the ComponentType
type helper, you can ensure that only components that accept prop1
are passed to this array as seen in tests2
:
const tests2: Array<React.ComponentType<{ prop1: string }>> = [
FuncComponent,
ClassComponent,
];
If we change the prop name in ClassComponent
to propTwo
, we will see an error because propOne
is not assignable to propTwo
:
class ClassComponent extends React.Component<{
prop2: string;
}> {
render(): React.ReactNode {
this.props.prop2;
return null;
}
}
const tests2: Array<React.ComponentType<{ prop1: string }>> = [
FuncComponent,
ClassComponent, // Error!
];
// Error message on ClassComponent:
// Type 'ComponentType<{ prop2: string; }>' is not assignable to type 'ComponentType<{ prop1: string; }>'.
This demonstrates that ComponentType
works can represent either functional or class components.
ComponentType
is useful when working with higher-order components when you want to ensure that a specific prop type is being passed to a component.