Borislav Hadzhiev
Sat Oct 30 2021·2 min read
Photo by Thought Catalog
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.
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.
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 conditional check would fail if someone passed in a plain object with a
then
property that is a function:
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.
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.
null
.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));
null
has a type of object
. This is an old bug in JavaScript that has not been fixed for backwards compatibility issues.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.
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.
then
method. It's a matter of personal preference how robust you want the solution to be.