nick.skriabin
nick.skriabin

Reputation: 873

Generic React Component with TypeScript

Not sure if the name "generic component" is correct, nonetheless I cannot come up with the right way of doing that.

The idea is to have a component that accepts tag as a prop, and that tag can be either a string (tag name) or a component constructor (FC, class component).

Here's the example code of what I'm trying to achieve

export const MyComponent = () => {
  return (
    <GeneicComponent tag="span">
      {/* some content here */}
    </GeneicComponent>
  )
}

export const MyComponent2 = () => {
  return (
    <GeneicComponent tag={SomeCustomComponent} {/* SomeCustomComponents props */}>
      {/* some content here */}
    </GeneicComponent>
  )
}

This approach works just fine until you're trying to pass extra props. GenericComponent must infer those props from tag and extend its own props with inferred ones, yet I have no idea now how to do that. Another problem is to infer props when the tag name passed as a string. I'm pretty sure it's something related to JSX.IntrinsicElements but had no luck experimenting with that.

Appreciate any suggestions.

Upvotes: 1

Views: 402

Answers (1)

Jonas Wilms
Jonas Wilms

Reputation: 138267

The component is just a function and it's props are just the first parameter to that function. One can derive the parameter type from a function type:

 function GenericComponent<T extends Function>(
   props: { tag: T } & { [key in keyof Parameters<T>[0]]: Parameters<T>[0][key] }
 ) { /*...*/ }

Upvotes: 2

Related Questions