TypeError: "X" is not a constructor in JavaScript [Solved]

avatar
Borislav Hadzhiev

Last updated: Mar 2, 2024
3 min

banner

# TypeError: "X" is not a constructor in JavaScript [Solved]

The "TypeError: 'X' is not a constructor" in JavaScript occurs for multiple reasons:

  1. Attempting to use a value that is not a constructor as a constructor.
  2. Mixing up default and named imports.
  3. Using an arrow function as a constructor.
  4. Calling Promise.resolve() and Promise.reject() with the new operator.

typeerror is not a constructor

Here are two examples of how the error occurs.

index.js
const obj = {}; // ⛔️ TypeError: obj is not a constructor const p = new obj(); // ------------------------------------------ const Animal = 42; // ⛔️ TypeError: Animal is not a constructor const a1 = new Animal();

We tried to instantiate a value that is not a constructor as a constructor, which caused the error.

# Only use the 'new' operator with valid constructors

Make sure to only use the new operator on valid constructors, e.g. classes or constructor functions.

Note that arrow functions cannot be used as constructors.

index.js
// ✅ Class constructor class Person { constructor(first, last) { this.first = first; this.last = last; } getName() { return `${this.first} ${this.last}`; } } const p1 = new Person('James', 'Doe'); console.log(p1.first); // 👉️ James console.log(p1.last); // 👉️ Doe console.log(p1.getName()); // 👉️ James Doe const p2 = new Person('Jane', 'Doe'); console.log(p2.getName()); // 👉️ Jane Doe

only use new operator with valid constructors

The code for this article is available on GitHub

The code sample shows how to use a class as a constructor.

However, you can also use functions as constructors.

index.js
// ✅ Function constructor function Animal(color, speed) { this.color = color; this.speed = speed; } const a1 = new Animal('green', 25); console.log(a1.speed); // 👉️ 25 const a2 = new Animal('red', 35); console.log(a2.speed); // 👉️ 35

# Arrow functions cannot be used as constructors

Note that arrow functions cannot be used as constructors. Arrow functions have the this keyword bound to the enclosing scope.

index.js
const Animal = color => { this.color = color; }; // ⛔️ TypeError: Animal is not a constructor const a = new Animal('green');

arrow functions cannot be used as constructors

The code for this article is available on GitHub

Instead, you should either use a class or a named function as a constructor, like in the previous example.

# The ES6 object method shorthand cannot be used as a constructor

The ES6 object method shorthand also cannot be used as a constructor.

index.js
const obj = { // 👇️ named function person: function Person(first) { this.first = first; }, // 👇️ arrow function animal: color => { this.color = color; }, // 👇️ shorthand movie(title) { this.title = title; }, }; // ✅ Works const p = new obj.person('James'); // ⛔️ obj.animal is not a constructor const a = new obj.animal('green'); // ⛔️ obj.movie is not a constructor const m = new obj.movie('example');
The code for this article is available on GitHub

Another common cause of the error is trying to use the Promise.resolve() and Promise.reject() methods with the new operator.

index.js
// ⛔️ Promise.resolve is not a constructor const res = new Promise.resolve('yay'); // ⛔️ Promise.reject is not a constructor const rej = new Promise.reject('boom');

Instead, omit the new operator when using the Promise.resolve and Promise.reject methods.

index.js
// ✅ works const resolvePromise = () => { return Promise.resolve('resolved'); }; // ✅ works const rejectedPromise = () => { return Promise.reject('rejected'); };

omit new operator when using promise resolve reject

The error also occurs when mixing up default and named imports in a codebase.

# Make sure you haven't mixed up default and named imports

Always make sure to import default exports without curly braces and named exports with curly braces.

You can use default imports/exports with ES6 modules in the following way:

index.js
// 👇️ default export export default function sum(a, b) { return a + b; }

And import the function in the other file.

another-file.js
// 👇️ default import import sum from './index.js'; console.log(sum(5, 5)); // 👉️ 10

Notice that we do not use curly braces to import a default export.

You can only have 1 default export per file.

Here's how you use named imports/exports.

index.js
// 👇️ named export export function sum(a, b) { return a + b; }

And now we use a named import in the other file.

another-file.js
// 👇️ named import import {sum} from './index.js'; console.log(sum(5, 5)); // 👉️ 10

Notice that we use curly braces when importing a named export.

You have to be consistent with your imports and exports. Don't use curly braces when importing default exports and use curly braces when importing named exports.

You can also mix and match, here's an example.

index.js
// 👇️ named export export const num = 50; // 👇️ default export export default function sum(a, b) { return a + b; }

And here are the imports.

another-file.js
// 👇️ default and named imports import sum, {num} from './index.js'; console.log(sum(5, 5)); // 👉️ 10 console.log(num); // 👉️ 50

We used a default import to import the sum function and a named import to import the num variable.

# Conclusion

To solve the "TypeError: 'X' is not a constructor" in JavaScript, make sure to only use the new operator on valid constructors, e.g. classes or constructor functions.

Note that arrow functions cannot be used as constructors.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.