JavaScript typeof Operator: Every Result and Its Quirks
Contents
The typeof operator returns a string that tells you the type of a value. It’s how you check, at runtime, whether something is a number, a string, a function, and so on:
typeof 42 returns "number", typeof "hi" returns "string".
It can only ever return one of eight strings, but a few of them are surprising. Here’s the full list, and how to handle the cases typeof gets “wrong”.
Every typeof result
| Value | typeof returns |
|---|---|
undefined |
"undefined" |
true, false |
"boolean" |
42, 3.14, NaN, Infinity |
"number" |
10n |
"bigint" |
"text", '' |
"string" |
Symbol('id') |
"symbol" |
| Functions, arrow functions, classes | "function" |
Objects, arrays, null, dates, regexes, maps |
"object" |
The syntax
typeof is an operator, not a function, so parentheses are optional. They’re handy for expressions, because typeof binds tighter than most operators.
typeof 'hello'; // "string"
typeof('hello'); // "string" (same thing)
typeof 1 + 2; // "number2" → (typeof 1) + 2
typeof (1 + 2); // "number"
The quirks
typeof null is "object"
A bug from the first version of JavaScript in 1995 that can never be fixed without breaking the web. Check for null directly instead.
typeof null; // "object" (!)
value === null; // the right check
// "is it a real object?"
value !== null && typeof value === 'object';
Arrays are "object"
Arrays are objects in JavaScript, so typeof can’t tell them apart. Use Array.isArray().
typeof [1, 2, 3]; // "object"
Array.isArray([1, 2, 3]); // true
Array.isArray({}); // false
NaN is a "number"
“Not a Number” is technically a numeric value: the result of failed math. Use Number.isNaN() to detect it, or Number.isFinite() to check for a usable number. You usually get NaN when you convert a string to a number and the string isn’t numeric.
typeof NaN; // "number"
Number.isNaN(NaN); // true
Number.isFinite('42'); // false: strings aren't numbers
Number.isFinite(42); // true
Classes are "function"
A class is a special kind of function under the hood.
class User {}
typeof User; // "function"
typeof new User(); // "object"
Wrapper objects
new String(), new Number() and new Boolean() create objects, not primitives. You almost never want them; call the functions without new to convert values.
typeof new String('hi'); // "object"
typeof String(42); // "string" (conversion, no new)
Practical uses
Check if a variable exists
typeof is the only way to check an undeclared variable without a ReferenceError. That’s useful for feature detection and code that runs in both browsers and Node.js. (It does throw for let and const variables used before their declaration.)
if (typeof window !== 'undefined') {
// running in a browser
}
if (typeof gtag === 'function') {
gtag('event', 'signup');
}
notDeclared; // ReferenceError
typeof notDeclared; // "undefined", no error
Validate function arguments
A quick guard at the top of a function catches wrong input early, with a clear error.
function formatPrice(amount, currency = 'USD') {
if (typeof amount !== 'number' || !Number.isFinite(amount)) {
throw new TypeError(`amount must be a number, got ${typeof amount}`);
}
return new Intl.NumberFormat('en-US', { style: 'currency', currency }).format(amount);
}
Get a precise type for anything
When you need to tell dates, regexes, maps and null apart, Object.prototype.toString gives a more detailed answer.
const type = (v) => Object.prototype.toString.call(v).slice(8, -1);
type(null); // "Null"
type([]); // "Array"
type(new Date()); // "Date"
type(/x/); // "RegExp"
type(new Map()); // "Map"
typeof vs instanceof
typeof checks a value’s basic type and works best for primitives. instanceof checks whether an object was created by a specific class or constructor, so it’s for objects: date instanceof Date, error instanceof TypeError. In TypeScript, both act as type guards and narrow the type inside an if. For logging what you’ve got while debugging, console.log plus typeof goes a long way; here are more ways to use console.log like a pro.
FAQ
Why does typeof null return “object”?
In the original JavaScript engine, values were stored with a type tag, and objects had the tag 0. null was the null pointer, which was also 0, so it was reported as an object. Fixing it would break existing websites, so it stays. It’s a classic interview question; try it and more in this JavaScript typeof quiz.
How do I check if a value is an array?
Array.isArray(value). typeof returns "object" for arrays.
How do I check if something is a function?
typeof value === 'function'. It works for regular functions, arrow functions, async functions and classes.
Is typeof a function?
No, it’s a unary operator, like ! or -. That’s why typeof x works without parentheses, and why it’s on the list of JavaScript reserved words.