Introduction: Your component is "silent" because it doesn't know how to be born
You're writing TypeScript with React, everything is going smoothly. And then — bam! — the compiler throws a mysterious message in your face:
JSX element type 'MyComponent' does not have any construct or call signatures.Sound familiar? If you're a beginner, this error might seem like an incantation from a parallel world. But don't panic. In reality, it's simple: TypeScript is telling you that what you're trying to use as a JSX component is not actually a function or a class that can be "called" or "constructed".
In this article, we'll break down this error in simple terms: why it occurs, how to fix it, and what these "construct or call signatures" actually mean. Let's go — we'll figure it out with fun and examples!
What does "construct or call signatures" mean?
Let's imagine a JSX component is a restaurant. You walk in, sit at a table (pass props) and wait for your food to be brought to you (return JSX). But if the restaurant is closed for renovations or doesn't exist at all, you won't be able to place an order.
In TypeScript, a "construct signature" is the ability of a class to be called with new (like a constructor). A "call signature" is the ability of a function to be called directly. JSX components in React can be either functions or classes. If TypeScript doesn't see either of these in your "component" — it throws an error.
A typical case:
// Incorrectconst MyComponent = someObject;// <MyComponent /> — error!
// Correctconst MyComponent: React.FC<Props> = (props) => { return <div>Hello</div>;};// <MyComponent /> — worksThe error occurs when you try to use something in JSX that is not a function or a class. For example, a string, number, object, or uninitialized variable.
Top 5 causes of the error (with TypeScript code examples)
Let's break down the most common scenarios where you might run into this issue. For each case, I'll show what the problem looks like and how to fix it.
1. The component is an object, not a function
The most popular pitfall. You import something thinking it's a component, but it's a regular object with data or configuration.
// ❌ Errorimport userData from './userData';// userData = { name: 'Anna', age: 25 }function App() { return <userData />; // userData — object, not a component!}
// ✅ Fiximport UserCard from './UserCard';function App() { return <UserCard user={userData} />;}How to check: Hover over the variable in your IDE. If TypeScript shows the type object, Record<string, any>, or something similar without () => JSX.Element — it's not a component.
2. The component is a string or number
Sometimes, out of carelessness, you might pass a literal or a primitive type variable into JSX.
// ❌ Errorconst greeting = "Hello, world!";function App() { return <greeting />; // greeting — is a string}
// ✅ Fixfunction App() { return <h1>{greeting}</h1>; // Use it as text, not a component}3. The component is imported incorrectly
If you use export default and import without curly braces, but the export was named — you'll get undefined. And undefined in JSX is that very error.
// In file Button.tsxexport const Button = () => <button>Click</button>;// export default is missing!
// ❌ Errorimport Button from './Button'; // Button = undefinedfunction App() { return <Button />;}
// ✅ Fiximport { Button } from './Button'; // Named import// or add export default in Button.tsx