How to fix Type 'X' is not a constructor or has a signature in TypeScript
This TypeScript error occurs when attempting to instantiate a type with the new operator that lacks a constructor signature. It commonly happens when trying to use interfaces, type aliases, or incorrectly imported types as constructors.
Quick fix
Fixes Type 'X' is not a constructor or has a signature
import type { MyClass } from './my-class';
const instance = new MyClass(); // Error: not a constructor- Verify you are importing a value, not just a type
- Check for interface or type alias usage
- Fix module import mismatches
- Add constructor signature constraint to generic types
import type { MyClass } from './my-class';const instance = new MyClass(); // Error: not a constructorType 'X' is not a constructor or has a signature
What this error means
This error appears when TypeScript detects an attempt to use the `new` operator on a type that doesn't have a construct signature. In TypeScript, not all types can be instantiated - only classes and types with explicit constructor signatures can be used with `new`. The error most commonly occurs in scenarios like trying to instantiate an interface or type alias, using a type-only import as a constructor, or when there's a mismatch between how a module exports a class and how it's imported. TypeScript's type system distinguishes between the static side of a class (the constructor) and the instance side, and this error indicates that the type being used doesn't represent the constructor side. This can also occur with `esModuleInterop` settings when there's a mismatch between CommonJS and ES module exports, causing TypeScript to interpret a default export differently than expected.
Typical symptoms
- Compilation fails when trying to instantiate a type with new
- IDE shows red squiggly lines under new SomeType() expressions
- Error appears despite the class or constructor appearing to be correctly defined
- Code that worked in JavaScript fails when converted to TypeScript
- Runtime error "X is not a constructor" after successful compilation
Common causes
- Attempting to instantiate an interface or type alias with the new operator
- Using a type-only import instead of a value import
- Importing a class incorrectly due to module system mismatches (CommonJS vs ES modules)
- Trying to use a type parameter that is not constrained to have a constructor signature
- Importing from a module with default exports when using esModuleInterop
- Exporting a type and value with the same name, causing import confusion
- Using an abstract class without proper type constraints
How to fix "Type 'X' is not a constructor or has a signature"
Check your import statement to ensure you're importing the actual class or constructor, not a type definition.
Incorrect (type-only import):
import type { MyClass } from './my-class';
const instance = new MyClass(); // Error: not a constructorCorrect (value import):
import { MyClass } from './my-class';
const instance = new MyClass(); // WorksIf you're using import type, remove the type keyword or use a separate import for the value.
Interfaces and type aliases define shapes but cannot be instantiated. Replace them with classes if you need constructors.
Problem:
interface User {
name: string;
age: number;
}
const user = new User(); // Error: not a constructorSolution (use a class):
class User {
constructor(public name: string, public age: number) {}
}
const user = new User('Alice', 30); // WorksAlternatively, create an object literal or factory function instead of using new.
When using esModuleInterop, default exports may need different import syntax.
If you get this error with a library:
import * as EventEmitter from 'events';
const emitter = new EventEmitter(); // May failTry default import instead:
import EventEmitter from 'events';
const emitter = new EventEmitter(); // WorksOr check your tsconfig.json and ensure esModuleInterop is enabled:
{
"compilerOptions": {
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
}
}If using a generic type parameter that should be constructable, add a constructor constraint.
Problem:
function create<T>(Type: T): T {
return new Type(); // Error: not a constructor
}Solution (add constructor constraint):
function create<T>(Type: new () => T): T {
return new Type(); // Works
}
// Or with parameters:
function createWith<T>(Type: new (name: string) => T, name: string): T {
return new Type(name);
}The new () => T syntax indicates that Type must be a constructor function.
If you're exporting both a type and a value with the same name, ensure imports are correct.
Export file (my-module.ts):
// Export the class (value)
export class Logger {
log(msg: string) { console.log(msg); }
}
// Export the type (if needed separately)
export type { Logger as LoggerType };Import file:
// Import the class value
import { Logger } from './my-module';
const logger = new Logger(); // Works
// Or import both
import { Logger, type LoggerType } from './my-module';If the error occurs only at runtime, check your TypeScript compilation target.
In tsconfig.json, ensure your target is appropriate:
{
"compilerOptions": {
"target": "ES2015", // or higher
"module": "commonjs"
}
}Some class features require ES2015 or higher. If targeting ES5, ensure your transpilation is handling classes correctly. You may also need to check if polyfills are required for your environment.
Advanced notes
Constructor Signatures in Detail:
TypeScript distinguishes between the instance type of a class and its constructor type. The constructor type is represented using construct signatures: { new (...args): InstanceType }. This is particularly important when working with factory patterns or dependency injection.
esModuleInterop and Module Systems:
The esModuleInterop flag affects how TypeScript handles default exports from CommonJS modules. When enabled, it allows default imports from modules that don't explicitly have a default export, but this can sometimes cause type system confusion about what is and isn't a constructor. This is a common source of this error when migrating JavaScript codebases to TypeScript.
Abstract Classes:
Abstract classes cannot be instantiated directly but can be used in type positions that require constructor signatures if properly constrained:
abstract class Base {
abstract getValue(): number;
}
// This will error unless properly constrained
function factory<T extends Base>(Ctor: new () => T): T {
return new Ctor(); // T must be a concrete class, not abstract
}Type-Only Imports (TypeScript 3.8+):
The import type syntax was introduced to explicitly import only types, which are erased at runtime. This helps with tree-shaking but can cause this error if you accidentally use it for values you need to instantiate.
Frequently asked questions
- What does "Type 'X' is not a constructor or has a signature" mean?
- This error appears when TypeScript detects an attempt to use the new operator on a type that doesn't have a construct signature. In TypeScript, not all types can be instantiated - only classes and types with explicit constructor signatures can be used with new. The error most commonly occurs in scenarios like trying to instantiate an interface or type alias, using a type-only import as a constructor, or when there's a mismatch between how a module exports a class and how it's imported.
- How do I fix "Type 'X' is not a constructor or has a signature"?
- This TypeScript error occurs when attempting to instantiate a type with the new operator that lacks a constructor signature. It commonly happens when trying to use interfaces, type aliases, or incorrectly imported types as constructors.
- What causes "Type 'X' is not a constructor or has a signature"?
- Attempting to instantiate an interface or type alias with the new operator Using a type-only import instead of a value import Importing a class incorrectly due to module system mismatches (CommonJS vs ES modules)
- Is the "Type 'X' is not a constructor or has a signature" error serious?
- It is a medium-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐TypeScript Official Documentation
- ๐Typescriptlang.org - everyday-types.html(Official Docs)
- ๐Typescriptlang.org - classes.html(Official Docs)
- ๐Typescriptlang.org - functions.html(Official Docs)
- ๐Github.com - 21872(GitHub)
- ๐Github.com - 10262(GitHub)
- ๐