Check if a Value is a Promise using JavaScript

avatar

Borislav Hadzhiev

Sat Oct 30 20212 min read

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 our 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.

Our 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));
As surprizing as it may seem, 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"

To handle this in our function, we can add a condition to check that the passed in value is not null as well.

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 just 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 #

Join my newsletter

I'll send you 1 email a week with links to all of the articles I've written that week

Buy Me A Coffee