Reputation: 4327
Is there a way to use react's ComponentProps
type with generic-typed components?
For example:
function MyComponent<T extends string, N extends number>({ text, number }: { text: T; number: N }) {
return (
<div>
{text} - {number}
</div>
);
}
export type MyComponentProps = ComponentProps<typeof MyComponent>;
I expect MyComponentProps
to be something like...
type MyComponentPropsExpected<T extends string, N extends number> = {
text: T;
number: N;
}
With the generics preserved. However, the type just drops the generic and fills all generics with their extends
type. In this case the actual MyComponentProps
type is...
type MyComponentProps = {
text: string;
number: number;
}
See demo here
Upvotes: 2
Views: 1106
Reputation: 9701
MyComponent
has two type parameters T
and N
with each constrained to string
and number
respectively:
function MyComponent<T extends string, N extends number>(...) { ... }
However when the MyComponentProps
type is created, no types are passed into those parameters:
export type MyComponentProps = ComponentProps<typeof MyComponent>;
// ^^^^^^^^^^^
// No type arguments passed in
As a result, the resultant type is the type of the constrained component props.
You'll need to pass in types to MyComponent
:
type MyComponentProps = ComponentProps<typeof MyComponent<"text", 2>>;
However, this syntax is only available in TypeScript 4.7+, when instantiation expressions were introduced.
Prior to TypeScript 4.7, I would have pulled out the props into its own interface and used that instead of building a type from ComponentProps
:
interface MyComponentProps<T extends string, N extends number> {
text: T;
number: N;
}
function MyComponent<T extends string, N extends number>({
text,
number
}: MyComponentProps<T, N>) {
...
}
export const test2: MyComponentProps<"text", 2> = {
text: "text",
number: 2
};
Upvotes: 1