user3250645
user3250645

Reputation: 63

Using ReactType with JSX

I have a question regarding JSX and Typescript integration. Given the following code:

interface Props {
    component?: React.ReactType
}

class MyComponent extends React.Component<Props, void> {
    render() {
      var Comp = this.props.component
      return (<Comp></Comp>)
    }
}

I get: JSX element type 'Comp' does not have any construct or call signatures.

How do I fix this? Similar code works fine in Javascript where component has prop validator elementType from react-prop-types, so it could be either a string or component class.

Upvotes: 1

Views: 2693

Answers (3)

Justin Dang
Justin Dang

Reputation: 374

I will give you an example using the functional component:

type YourProps = { count: number };
type Props = {
  component: ElementType<YourProps>
}

function Parent({component}: Props): ReactElement {

  return (
    <>
      {React.createElement(component, {count: 1})}
    </>
  );
}

function Child({count}: YourProps) {
  return <>Count: {count}</>
}

function Root() {
  return <><Parent component={Child}/></>
}

In this case you will delegate the construction of element for the Parent component and it would natively create by using React API - createElement and passing props into it.

Upvotes: 0

mikebridge
mikebridge

Reputation: 4575

How are you creating the component that you're passing in? If you create it like this it should work:

interface MyProps {
    component?: React.ReactType;
}

class TestComponent extends React.Component<void, void> {
    render() {
        return <div>Test</div>;
    }
}

class MyComponent extends React.Component<MyProps, void> {
    render() {
        const Comp = this.props.component
        return (<Comp/>);
    }
}


class Parent extends React.Component<{}, {}> {
    render() {
       return (
          <MyComponent component={TestComponent}></MyComponent>
       )
    }
}

You could also pass an html element as a string (e.g. "div"), but I'm not sure if that's what you wanted to do.

Upvotes: 1

Konstantin Solomatov
Konstantin Solomatov

Reputation: 10332

If you take a look at the definition of react type in typing, you will find that you have a union type of 3 different types, one of which is a string. That's why you had such a problem. Try replacing React.ReactType with React.ComponentClass.

Upvotes: 1

Related Questions