Check if a Value is a Promise using JavaScript

avatar

Borislav Hadzhiev

Last updated: Aug 26, 2022

banner

Photo from Unsplash

Check if a Value is a Promise in JavaScript #

To check if a value is promise, check if the type of the value is an object and has a property named then of type function, e.g. typeof p === 'object' && typeof p.then === 'function'. If both conditions return true, the value is a promise.

index.js
function isPromise(p) { if (typeof p === 'object' && typeof p.then === 'function') { return true; } return false; } const p1 = new Promise(resolve => { resolve(10); }); console.log(isPromise(p1)); // 👉️ true console.log(isPromise({})); // 👉️ false

We used the logical AND (&&) operator to chain 2 conditions.

Both conditions have to return a truthy value for the if block to run.

All promises have a type of object, so this is what we check for first.

index.js
const p1 = new Promise(resolve => { resolve(10); }); console.log(typeof p1); // 👉️ "object"

We then access the then property on the object and check if it has a type of function.

Promises have a .then() and .catch() methods.

This approach is called duck typing. We basically say - "if the value is an object and has these specific properties/methods, then it must be a promise".

This conditional check would fail if someone passed in a plain object with a then property that is a function:

index.js
function isPromise(p) { if (typeof p === 'object' && typeof p.then === 'function') { return true; } return false; } console.log(isPromise({then: () => {}})); // 👉️ true

We satisfied both conditions and got a false positive.

To make the solution more robust, you can add a check for the catch method as well.

index.js
function isPromise(p) { if ( typeof p === 'object' && typeof p.then === 'function' && typeof p.catch === 'function' ) { return true; } return false; } console.log(isPromise({then: () => {}})); // 👉️ false

We added a condition that checks if the object contains a catch method as well.

The function would return an error if someone passed in a value of null.
index.js
function isPromise(p) { if ( typeof p === 'object' && typeof p.then === 'function' && typeof p.catch === 'function' ) { return true; } return false; } // ❌ Error: Cannot read property 'then' of null console.log(isPromise(null));
Unfortunately, null has a type of object. This is an old bug in JavaScript that has not been fixed for backwards compatibility issues.
index.js
console.log(typeof null); // 👉️ "object"

We can add a condition that checks if the passed-in value is not null.

index.js
function isPromise(p) { if ( p !== null && typeof p === 'object' && typeof p.then === 'function' && typeof p.catch === 'function' ) { return true; } return false; } console.log(isPromise(null)); // 👉️ false const p1 = new Promise(resolve => { resolve(10); }); console.log(isPromise(p1)); // 👉️ true

Now our solution is a bit more robust. The only way to get a false positive would be to pass an object that contains methods named then() and catch(), but is not an actual promise.

Your use case might not require this over-engineered solution. You might be just fine with checking for an object that has the then method. It's a matter of personal preference how robust you want the solution to be.

Further Reading #

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.