Check if a Value is a Promise using JavaScript

avatar
Borislav Hadzhiev

Last updated: Mar 3, 2024
3 min

banner

# Check if a Value is a Promise in JavaScript

To check if a value is a Promise:

  1. Check if the type of the value is an object
  2. Check if the object has a property named then of type function.
  3. 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

check if value is promise

The code for this article is available on GitHub

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

The if block is run only if both conditions evaluate to true.

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"

all promises have type of object

The code for this article is available on GitHub

We 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 of type function.

index.js
function isPromise(p) { if (typeof p === 'object' && typeof p.then === 'function') { return true; } return false; } console.log(isPromise({then: () => {}})); // ๐Ÿ‘‰๏ธ true

passing plain object with then property to the function

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

checking for the catch method as well

The code for this article is available on GitHub

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

The function would throw an error if someone called it with anull value.
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 backward 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
The code for this article is available on GitHub

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.

I've also written an article on how to access the value of a Promise.

# Using Promise.resolve() instead

As an alternative to checking if the value is a Promise, you could directly use the Promise.resolve() method.

index.js
const value = Promise.resolve(42); Promise.resolve(value).then(value => { console.log(value); // ๐Ÿ‘‰๏ธ 42 });

using promise resolve instead

The value in the example doesn't necessarily have to be a Promise.

index.js
const value = 42; Promise.resolve(value).then(value => { console.log(value); // ๐Ÿ‘‰๏ธ 42 });
The code for this article is available on GitHub

Either way, our code works as expected.

The Promise.resolve() method resolves the supplied value to a Promise.

If the provided value is a Promise, then the Promise is returned, otherwise, the method returns a Promise that is resolved with the supplied value.

If the value is not a Promise, we wrap it in one to be able to use the .then() method.

If the value is a Promise, it gets returned as is and we are still able to use the .then() method.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

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.

Copyright ยฉ 2024 Borislav Hadzhiev