Reputation: 63
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
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
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
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