Last updated: Feb 29, 2024
Reading timeยท4 min

The error "JSX element type does not have any construct or call signatures" occurs when we try to pass an element or a React component as props to another component but type the prop incorrectly.
To solve the error, use the React.ElementType type.

Here is an example of how the error occurs.
import React from 'react'; interface Props { comp: JSX.Element; } const Wrapper: React.FunctionComponent<Props> = props => { const {comp: Comp} = props; // โ๏ธ JSX element type 'Comp' does not have any construct or call signatures.ts(2604) return ( <div> <Comp name="Bobby" /> </div> ); }; const App: React.FunctionComponent = () => { const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>; return ( <div> <Wrapper comp={heading} /> </div> ); }; export default App;
We tried to pass a React component as a prop to the Wrapper component, but
have typed it as JSX.Element.
React.ElementTypeTo solve the error, type the prop as React.ElementType.
import React from 'react'; interface Props { comp: React.ElementType; // ๐๏ธ type it as React.ElementType } const Wrapper: React.FunctionComponent<Props> = props => { // ๐๏ธ component names must start with a capital letter const {comp: Comp} = props; return ( <div> <Comp name="Bobby" /> </div> ); }; const App: React.FunctionComponent = () => { // ๐๏ธ takes a name prop const heading = ({name}: {name: string}) => ( <h2>Hello {name}</h2> ); return ( <div> <Wrapper comp={heading} /> </div> ); }; export default App;

React.ElementType can be passed a generic for the type of props the element expects.In this example, we would have to pass it an object that has a name property
of type string because that's the prop the heading component takes.
import React from 'react'; interface Props { // โ explicitly type props comp takes comp: React.ElementType<{name: string}>; } const Wrapper: React.FunctionComponent<Props> = props => { // ๐๏ธ component names must start with a capital letter const {comp: Comp} = props; return ( <div> <Comp name="Bobby" /> </div> ); }; const App: React.FunctionComponent = () => { const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>; return ( <div> <Wrapper comp={heading} /> </div> ); }; export default App;
Now we explicitly typed the props the comp element takes when used. This helps
us leverage our IDE for auto-completion when passing props to the component.
React.ComponentType to solve the errorWe could also use the React.ComponentType, but then we are required to type
the props.
import React from 'react'; interface Props { // ๐๏ธ now using React.ComponentType ๐๏ธ comp: React.ComponentType<{name: string}>; } const Wrapper: React.FunctionComponent<Props> = props => { // ๐๏ธ component names must start with a capital letter const {comp: Comp} = props; return ( <div> <Comp name="Bobby" /> </div> ); }; const App: React.FunctionComponent = () => { const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>; return ( <div> <Wrapper comp={heading} /> </div> ); }; export default App;
The generic in React.ComponentType doesn't default to the any type, so we
are required to explicitly type the props.
If you need to pass a JSX element as props to a component, and not an actual
component, then JSX.Element is the correct type.
import React from 'react'; interface Props { // ๐๏ธ using JSX.Element type comp: JSX.Element; } const Wrapper: React.FunctionComponent<Props> = props => { const {comp: Comp} = props; // ๐๏ธ use as {Comp} return <div>{Comp}</div>; }; const App: React.FunctionComponent = () => { const Heading = ({name}: {name: string}) => <h2>Hello {name}</h2>; // ๐๏ธ we are passing an actual JSX element // because we didn't pass it as comp={Heading} return ( <div> <Wrapper comp={<Heading name="Bobby" />} /> </div> ); }; export default App;
We typed the comp prop as JSX.Element because we are passing an actual JSX
element (not a component) to the Wrapper component.
We are passing a JSX element because we passed the prop as comp={<Heading />}
instead of comp={(props) => <h2>Hello world</h2>}.
We shouldn't try to use the JSX element as a component in our Wrapper
component, e.g. don't do <Comp />, instead do {Comp}.
We haven't passed an actual component as a prop, we passed a JSX element, so it shouldn't be used as a component.
If you pass multiple child elements to a component that takes a single
JSX.Element, you'd get the error
This JSX tag's children prop expects single child of type Element, but multiple children were provided.
If none of the previous suggestions helped, try to update the versions of your React typings by running the following commands.
# ๐๏ธ with NPM npm install react@latest react-dom@latest npm install --save-dev @types/react@latest @types/react-dom@latest # ---------------------------------------------- # ๐๏ธ with YARN yarn add react@latest react-dom@latest yarn add @types/react@latest @types/react-dom@latest --dev

I've written a detailed guide on how to update your React.js typings correctly.
You can learn more about the related topics by checking out the following tutorials: