Solve - TypeError: "X" is not a constructor in JavaScript

avatar

Borislav Hadzhiev

Last updated: Jul 25, 2022

banner

Check out my new book

Solve - TypeError: "X" is not a constructor in JavaScript #

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's an example of how the error occurs.

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

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

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.

index.js
// ✅ Class constructor class Person { constructor(first, last) { this.first = first; this.last = last; } getName() { return `${this.first} ${this.last}`; } } const p = new Person('James', 'Doe'); // ✅ Function constructor function Animal(color) { this.color = color; } const a = new Animal('green');

The first example is class constructor and the second - a function constructor.

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');

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

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');

Another common cause of the "TypeError: 'X' is not a constructor" 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 res = Promise.resolve('yay'); // ✅ Works const rej = Promise.reject('boom');

Lastly, the error also occurs when mixing up default and named imports in a codebase.

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.

Use the search field on my Home Page to filter through my more than 3,000 articles.