Last updated: Mar 2, 2024
Reading time·3 min
The "TypeError: 'X' is not a constructor" in JavaScript occurs for multiple reasons:
Promise.resolve()
and Promise.reject()
with the new
operator.Here are two examples of how the error occurs.
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.
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.
// ✅ 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
The code sample shows how to use a class as a constructor.
However, you can also use functions as constructors.
// ✅ 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
Note that arrow functions cannot be used as constructors. Arrow functions have
the this
keyword bound to the enclosing scope.
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.
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 error is trying to use the Promise.resolve() and Promise.reject() methods with the new operator.
// ⛔️ 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.
// ✅ works const resolvePromise = () => { return Promise.resolve('resolved'); }; // ✅ works const rejectedPromise = () => { return Promise.reject('rejected'); };
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:
// 👇️ default export export default function sum(a, b) { return a + b; }
And import the function in the other file.
// 👇️ 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.
Here's how you use named imports/exports.
// 👇️ named export export function sum(a, b) { return a + b; }
And now we use a named import in the other file.
// 👇️ 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 can also mix and match, here's an example.
// 👇️ named export export const num = 50; // 👇️ default export export default function sum(a, b) { return a + b; }
And here are the imports.
// 👇️ 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.
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.