Home > Blockchain >  React.createElement with typescript error when trying to pass props
React.createElement with typescript error when trying to pass props

Time:02-12

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'.

  • Related