"TypeError: X is not a constructor" means JavaScript tried to use new or super() on a value that isn't a constructor function or class.
What "TypeError: X is not a constructor" Means
This runtime error fires in browsers and Node.js when the new operator or super() call encounters a value that has no [[Construct]] internal method. Plain objects, arrow functions, and class instances all fail this check — only functions and classes (with a prototype) can be constructors.
Why It Happens
The two most common causes are:
- Importing a module incorrectly — you imported a default export as a named export, or vice versa, so
Xresolves to an object orundefinedinstead of the class. - Using an arrow function as a constructor — arrow functions are syntactically forbidden from being constructors, so
newthrows this exact error.
Less common: calling a class method without binding it first, or a transpilation issue where Babel/TypeScript emits code that breaks the prototype chain.
Example Code That Triggers It
// module.ts
export default class User {
constructor(public name: string) {}
}
// app.ts
import { User } from "./module"; // Wrong: named import of a default export
const user = new User("Suhail");
// TypeError: User is not a constructor
The imported User is actually undefined because the module only has a default export, and new undefined produces this exact error.
How to Fix It
// module.ts
export default class User {
constructor(public name: string) {}
}
// app.ts
import User from "./module"; // Correct: default import
const user = new User("Suhail");
The fix is changing the import statement. Default exports must be imported without curly braces; named exports require them. This is the single most common cause of this error in real codebases.
Common Mistakes That Cause This
- Treating an object literal as a class —
const User = { name: "" }; new User()throws this. You need a class or constructor function, not an object. - Destructuring a class out of a namespace —
const { User } = require("module")whenmoduleexports the class asmodule.exports = User. You get{ default: User }instead, andUserbecomesundefined.
Both mistakes share a root cause: assuming the shape of an export without verifying it.
When Should You Worry About This?
You should worry when this error appears in production, not just locally. If it's happening in a browser, check your bundler config — a misconfigured tree-shaking step can strip class declarations. In Node.js, check if you're mixing require and import in the same file, which can cause the module system to resolve exports differently.
If it only happens in test environments, it's likely a mocking issue — your test framework is replacing the class with a plain object.
Next time this appears, check your import statement first — 80% of the time, you've got the wrong import syntax for how the module exports the class.