SKU // 99

JavaScript typeof

typeof is an operator that tells you what type a value is, as a string. It is the quickest type check in JavaScript and works well for primitives, but it has a few famous blind spots. This lesson covers every result and when to use something else.

// Every Possible Result

typeof only ever returns one of eight strings:

Expression Result
typeof "text""string"
typeof 42 / typeof NaN"number"
typeof 42n"bigint"
typeof true"boolean"
typeof undefined"undefined"
typeof Symbol()"symbol"
typeof function(){} / typeof class {}"function"
typeof {} / typeof [] / typeof new Date()"object"
typeof null"object" (a bug from 1995)

// It Always Returns a String

typeof 42              // "number"
typeof typeof 42       // "string"  (the result of typeof is a string)

if (typeof x === "number") { }   // compare against a string, in quotes
Watch out
typeof x === number (no quotes) compares against a variable named number, which does not exist. Always quote the type name.

// No Parentheses Needed

typeof is an operator like !, not a function. Parentheses are allowed but only group the expression:

typeof "a" + 1       // "string1"   typeof runs first, then + joins
typeof ("a" + 1)     // "string"    parentheses group the expression first
string1 string

// Blind Spot 1: null

const v = null;
typeof v === "object"   // true: misleading
v === null              // true: the right check

This means "is it an object?" needs two checks:

const isObject = v => v !== null && typeof v === "object";

// Blind Spot 2: Arrays and Other Objects

Every kind of object except functions reports "object". Use a more specific check:

typeof [1, 2]            // "object"
Array.isArray([1, 2])     // true
new Date() instanceof Date // true

// Blind Spot 3: NaN Is a "number"

const result = "abc" * 2;
typeof result          // "number"  (but it is NaN)
Number.isFinite(result) // false     the check you actually want
number false

// A Superpower: Undeclared Variables

Using a variable that was never declared normally throws an error. typeof is the one safe exception:

console.log(mystery);          // ReferenceError: mystery is not defined
console.log(typeof mystery);   // "undefined"  no error
ReferenceError: mystery is not defined undefined

That makes it useful for checking whether a feature exists before using it:

if (typeof structuredClone === "function") {
  // safe to use structuredClone in this browser
}
One Exception
A let or const used in its temporal dead zone (before its line) still throws, even inside typeof. The safety only applies to names that are not declared anywhere in scope.

// instanceof: Which Constructor Made It?

typeof cannot tell objects apart. instanceof can: it asks "was this object made by that constructor?"

const time = new Date();
const fruits = ["apples", "bananas", "oranges"];
const prices = new Map([["apples", 500], ["bananas", 300]]);
const unique = new Set(["apples", "bananas"]);

console.log(time instanceof Date, fruits instanceof Array);
console.log(prices instanceof Map, unique instanceof Set);
console.log(fruits instanceof Object);    // every array is also an Object
console.log("hi" instanceof String);      // primitives are not instances of anything
true true true true true false

// The constructor Property

Every value except null and undefined has a constructor property: the function that made it (for primitives, the wrapper that auto-boxing uses):

console.log([1, 2, 3].constructor === Array);
console.log(new Date().constructor === Date);
console.log(({ name: "John" }).constructor.name);
console.log((function () {}).constructor.name, "hi".constructor.name);
true true Object Function String
Trap: constructor can lie
constructor is an ordinary property, so any object can have its own. After const fake = { constructor: Array };, fake.constructor === Array is true, but Array.isArray(fake) is false. Prefer Array.isArray and instanceof.
W3Schools errors on its typeof page
  • Its constructor examples start lines with {name:'John',age:34}.constructor and function () {}.constructor. At the start of a statement, { opens a code block and function starts a function declaration, so these are SyntaxError: Unexpected token ':' and SyntaxError: Function statements require a function name. Wrap them in parentheses, as above.
  • It declares const fruits three times in a row. In one program, the second is SyntaxError: Identifier 'fruits' has already been declared.
  • It says a primitive "has no properties or methods." Auto-boxing (JS Primitive Data) is why "hi".length works anyway.

// The void Operator

void runs an expression, throws away the result, and always gives undefined:

let n = 0;
console.log(void 0);
console.log(void (n = 5), n);    // the assignment still happens
console.log(void 0 === undefined);
undefined undefined 5 true
Not recommended: javascript:void(0) links
In older web pages you will see <a href="javascript:void(0);">: a link that goes nowhere, so that JavaScript can handle the click instead. Avoid it. It mixes code into HTML, a link that goes nowhere confuses screen readers and keyboard users, and it breaks "open in new tab." If clicking something runs code, make it a <button>. In modern code you rarely need void at all: just write undefined.

// A Complete Type Check

function typeName(v) {
  if (v === null) return "null";
  if (Array.isArray(v)) return "array";
  if (typeof v === "number" && Number.isNaN(v)) return "NaN";
  return typeof v;
}

[null, [], NaN, 5, "hi", {}].map(typeName);
["null", "array", "NaN", "number", "string", "object"]

// Quick Check

What does this log?

console.log(typeof typeof undefined);
Show answer
string. typeof undefined is the string "undefined", and typeof of any string is "string".

What is the most reliable way to check whether x is an array?

  1. typeof x === "array"
  2. x.constructor === Array
  3. Array.isArray(x)
  4. typeof x === "object"
Show answer
C. A is never true, since typeof has no "array" result. B can be faked by any object with its own constructor property. D is also true for plain objects, dates, and null.

What does void (total = 10) give, and does total change?

Show answer
It gives undefined, and yes, total becomes 10. void runs the expression and only throws away its result.

// Try It

  1. Click Open Playground. Add a typeof line for every row of the table above and check the results
  2. Predict, then test: typeof typeof null
  3. Use typeof to safely check for a variable you never declared
  4. Open the typeName example with its Try it Yourself button and extend it so it also reports "date" for Date objects
// Video Walkthroughs
Last updated: Oct 10, 2026, 1:47 AM ET