I am trying to create dynamic components in react typescript but I am struggling to correctly type the props on it.
Here is a simpler version of what I'm doing.
interface ComponentProps {
title: string;
}
interface ArrInterface {
component: FC<ComponentProps>;
title: string
}
const Arr: ArrInterface = [
{ component: FooComponent, title: "foo"},
{ component: FooComponent, title: "bar"}
];
const FooComponent: FC<ComponentProps> = ({title}) => {
return <div>{title}</div>
}
const BarComponent: FC = () => {
return sectionsArr.map((section) => {
const {component, title} = section;
return React.createElement(component as FC, { title })
})
}
this is the error I am getting :
Argument of type '{ title: string; }' is not assignable to parameter of type ' Attributes'.
Object literal may only specify known properties, and 'title' does not exist in type 'Attributes'
it works if I do a ts-ignore on top of that line btw :)
Can someone please help me out on this one? What am I missing here?
CodePudding user response:
I found the solution myself :)
For those ending up with the same issue as I did, it turns out you need to pass the props type to createElement function.
So basically instead of doing
return React.createElement(component as FC, { title })
this should fix the issue
return React.createElement<ComponentProps>(component as FC, { title })
CodePudding user response:
The signature that TS uses for your React.createElement
is
function createElement<P extends {}>(
type: FunctionComponent<P>,
props?: Attributes & P | null,
...children: ReactNode[]): FunctionComponentElement<P>;
In your React.createElement(component as FC, { title })
call, you're passing a value (component
) with the type FC
as the argument named type
. FC
is defined as
type FC<P = {}> = FunctionComponent<P>;
So since you asserted component as FC
— without a type argument — TS now uses the default type for the type argument P
, namely {}
. Now the type of the props
argument is Attributes & {}
, which is the same as just Attributes
. And just like TS tells you, the property 'title' does not exist in type 'Attributes'.