I believe I have the answer for you. This is a copy of an Answer I wrote elsewhere on this site. Please let me know how it worked for you.
The following is a common typeof hack which is somewhat problematic::
const type = obj => Object.prototype.toString.call(obj);
type("abc");// [object String]
type(123);// [object Number]// What's with all the objects?
type([]);// [object Array]
type({});// [object Object]
type(Object.create(null));// [object Object]
type(-1/0);// [object Number] Not exactly a true number
type(NaN);// [object Number] WTF?
As you can see there are a few problems with it. It always returns two types wrapped in brackets with the first always an "object". This makes the first type useless information if it is always returned. Secondly it is somehat limited in what it distinguishes. It cannot tell us if an object was created as a literal (plain) or with Object.create() which would require the keyword "new" when called. It also falesly calls infinity and NaN a number.
I wish to share a better typeof function that fixes all of those things. It works for all primitives including symbols, anomalies (errors, undefined, null, and NaN), most common cases of native objects and functions (Array, Map, Object, Function, Math, Date, Promise, and many more), and it can even detect between user made objects (identified as Plain) and DOM elements (identified as HTML). It should work for all modern and somewhat older browsers. It is broken down into several functions to make the code more user friendly:
const isDOM = obj => (obj.nodeType && !isPlain(obj)) ? true : false;
const isPlain = obj => obj ? obj.constructor === {}.constructor : false;
const sanString = str => str.replace(/[^a-zA-Z ]/g, "");
const isNaN = obj => (Object.is(obj, NaN) === true) ? true : false;
function objType(obj){
if(obj === undefined) return undefined;
if(obj === Infinity) return Infinity;
if(obj === -Infinity) return -Infinity;
if(isDOM(obj)) return 'HTML';
let str = Object.prototype.toString.call(obj);
if(str === '[object Object]' && isPlain(obj)) return 'Plain';
str = sanString(str).split(' ');
if(str[1] === 'Number' && isNaN(obj)) return NaN;
return str[1];}
}
Use like this:
objType(null);// Null
objType(undefined);// undefined
objType("abc");// String
objType(123);// Number
objType([]);// Array
objType({});// Plain not [object Object]
objType(Object.create(null));// Object is what we want
objType(document.body);// HTML
objType(-1/0);// -Infinity
objType(NaN);// NaN