A better typeof
Object.prototype.toString and friends.
Implement a typeOf function that returns accurate type strings for all JavaScript values — including the ones typeof gets wrong.
The Problem
typeof has some well-known gaps:
typeof null; // 'object' — wrongtypeof []; // 'object' — not specific enoughtypeof new Date(); // 'object' — not specific enoughtypeof /regex/; // 'object' — not specific enoughFor real type checking, you need Object.prototype.toString.
The Implementation
function typeOf(value) { return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();}
typeOf(null); // 'null'typeOf([]); // 'array'typeOf(new Date()); // 'date'typeOf(/regex/); // 'regexp'typeOf(42); // 'number'typeOf("hello"); // 'string'typeOf(undefined); // 'undefined'typeOf({}); // 'object'typeOf(() => {}); // 'function'Object.prototype.toString.call(value) returns a string like "[object Array]". .slice(8, -1) removes the [object prefix and ] suffix. .toLowerCase() normalizes the casing.
Why call Is Needed
toString can be overridden on any object. Calling it via Object.prototype.toString.call(value) bypasses any override and uses the original implementation, which inspects the internal [[Class]] tag.
Extended Version
function typeOf(value) { if (value === null) return "null"; if (Array.isArray(value)) return "array"; return typeof value;}This shorter version handles the most common gaps without Object.prototype.toString. Use whichever level of precision you need.
Why It Matters
typeof is fine for primitives. For anything more complex — runtime type guards, serialization, debugging utilities — you need the full picture.