Reputation: 3697
I have the following interfaces:
interface ButtonProps {
name: string;
}
interface IconButtonProps {
name: string;
icon: string;
}
I'm trying to create the type for the following component:
<MyGenericComponent component={button} name="button">...
<MyGenericComponent component={iconButton} name="icon-button" icon="icon">...
The idea is that I'm unable to type the interface that would represent MyGenericComponentProps
so that it can accept a react component in the component
prop as long as all other props given to it are those that the given component would accept!
Something like this:
interface MyGenericComponentProps<T> extends T {
component: React.FC<T>;
}
...where T
above can be ButtonProps
or IconButtonProps
. I know I cannot extend T
because it's unknown statically, but then how do I ensure that the rest of the props given are those of either ButtonProps
or IconButtonProps
?
UPDATE: here's the component definition after answer:
import React from 'react';
import { ButtonProps, IconButtonProps } from '@material-ui/core';
type MyGenericComponentProps<T> = {
component: React.FC<T>;
} & {
[key in keyof T]: T[key];
};
const MyGenericComponent = <T extends object>({ component, ...props }: MyGenericComponentProps<T>) => {
// ... more code here
const Component = component;
return <Component {...props} />;
};
export default MyGenericComponent;
Upvotes: 2
Views: 1484
Reputation: 1337
If it doesn't make sense what kind of TS entity will be used (type or interface) then you can type it as a type instead of an interface:
type MyGenericComponentProps<T> = {
component: React.FC<T>;
} & {
[key in keyof T]: T[key];
}
[UPDATE]:
You need to modify and even simplify some fragments:
type MyGenericComponentProps<T> = {
component: React.FC<T>;
props: T;
}
const MyGenericComponent = <T extends object>({component: Component, props}: MyGenericComponentProps<T>) => {
// ... more code here
return <Component {...props}/>;
};
Upvotes: 2
Reputation: 878
interface ButtonProps {
name: string;
}
interface IconButtonProps extends ButtonProps{
icon?: string;
}
and
interface MyGenericComponentProps<IconButtonProps>{
component: React.FC<IconButtonProps>;
}
do not know about react, but with typescript you can do extend interfaces and declare optional properties. Then this would accept ButtonProps and IconButtonProps
Upvotes: 1