typeof
BaselineWidely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Thetypeof
operator returns a string indicating the type of the operand's value.
Try it
console.log(typeof 42);// Expected output: "number"console.log(typeof "blubber");// Expected output: "string"console.log(typeof true);// Expected output: "boolean"console.log(typeof undeclaredVariable);// Expected output: "undefined"
Syntax
typeof operand
Parameters
Description
The following table summarizes the possible return values oftypeof
. For more information about types and primitives, see also theJavaScript data structure page.
Type | Result |
---|---|
Undefined | "undefined" |
Null | "object" (reason) |
Boolean | "boolean" |
Number | "number" |
BigInt | "bigint" |
String | "string" |
Symbol | "symbol" |
Function (implements [[Call]] in ECMA-262 terms;classes are functions as well) | "function" |
Any other object | "object" |
This list of values is exhaustive. No spec-compliant engines are reported to produce (or had historically produced) values other than those listed.
Examples
Basic usage
// Numberstypeof 37 === "number";typeof 3.14 === "number";typeof 42 === "number";typeof Math.LN2 === "number";typeof Infinity === "number";typeof NaN === "number"; // Despite being "Not-A-Number"typeof Number("1") === "number"; // Number tries to parse things into numberstypeof Number("shoe") === "number"; // including values that cannot be type coerced to a numbertypeof 42n === "bigint";// Stringstypeof "" === "string";typeof "bla" === "string";typeof `template literal` === "string";typeof "1" === "string"; // note that a number within a string is still typeof stringtypeof typeof 1 === "string"; // typeof always returns a stringtypeof String(1) === "string"; // String converts anything into a string, safer than toString// Booleanstypeof true === "boolean";typeof false === "boolean";typeof Boolean(1) === "boolean"; // Boolean() will convert values based on if they're truthy or falsytypeof !!1 === "boolean"; // two calls of the ! (logical NOT) operator are equivalent to Boolean()// Symbolstypeof Symbol() === "symbol";typeof Symbol("foo") === "symbol";typeof Symbol.iterator === "symbol";// Undefinedtypeof undefined === "undefined";typeof declaredButUndefinedVariable === "undefined";typeof undeclaredVariable === "undefined";// Objectstypeof { a: 1 } === "object";// use Array.isArray or Object.prototype.toString.call// to differentiate regular objects from arraystypeof [1, 2, 4] === "object";typeof new Date() === "object";typeof /regex/ === "object";// The following are confusing, dangerous, and wasteful. Avoid them.typeof new Boolean(true) === "object";typeof new Number(1) === "object";typeof new String("abc") === "object";// Functionstypeof function () {} === "function";typeof class C {} === "function";typeof Math.sin === "function";
typeof null
// This stands since the beginning of JavaScripttypeof null === "object";
In the first implementation of JavaScript, JavaScript values were represented as a type tag and a value. The type tag for objects was0
.null
was represented as the NULL pointer (0x00
in most platforms). Consequently,null
had0
as type tag, hence thetypeof
return value"object"
. (reference)
A fix was proposed for ECMAScript (via an opt-in), butwas rejected. It would have resulted intypeof null === "null"
.
Using new operator
All constructor functions called withnew
will return non-primitives ("object"
or"function"
). Most return objects, with the notable exception beingFunction
, which returns a function.
const str = new String("String");const num = new Number(100);typeof str; // "object"typeof num; // "object"const func = new Function();typeof func; // "function"
Need for parentheses in syntax
Thetypeof
operator has higherprecedence than binary operators like addition (+
). Therefore, parentheses are needed to evaluate the type of an addition result.
// Parentheses can be used for determining the data type of expressions.const someData = 99;typeof someData + " foo"; // "number foo"typeof (someData + " foo"); // "string"
Interaction with undeclared and uninitialized variables
typeof
is generally always guaranteed to return a string for any operand it is supplied with. Even with undeclared identifiers,typeof
will return"undefined"
instead of throwing an error.
typeof undeclaredVariable; // "undefined"
However, usingtypeof
on lexical declarations (let
const
, andclass
) in the same block before the place of declaration will throw aReferenceError
. Block scoped variables are in atemporal dead zone from the start of the block until the initialization is processed, during which it will throw an error if accessed.
typeof newLetVariable; // ReferenceErrortypeof newConstVariable; // ReferenceErrortypeof newClass; // ReferenceErrorlet newLetVariable;const newConstVariable = "hello";class newClass {}
Exceptional behavior of document.all
All current browsers expose a non-standard host objectdocument.all
with typeundefined
.
typeof document.all === "undefined";
Althoughdocument.all
is alsofalsy andloosely equal toundefined
, it is notundefined
. The case ofdocument.all
having type"undefined"
is classified in the web standards as a "willful violation" of the original ECMAScript standard for web compatibility.
Custom method that gets a more specific type
typeof
is very useful, but it's not as versatile as might be required. For example,typeof []
is"object"
, as well astypeof new Date()
,typeof /abc/
, etc.
For greater specificity in checking types, here we present a customtype(value)
function, which mostly mimics the behavior oftypeof
, but for non-primitives (i.e., objects and functions), it returns a more granular type name where possible.
function type(value) { if (value === null) { return "null"; } const baseType = typeof value; // Primitive types if (!["object", "function"].includes(baseType)) { return baseType; } // Symbol.toStringTag often specifies the "display name" of the // object's class. It's used in Object.prototype.toString(). const tag = value[Symbol.toStringTag]; if (typeof tag === "string") { return tag; } // If it's a function whose source code starts with the "class" keyword if ( baseType === "function" && Function.prototype.toString.call(value).startsWith("class") ) { return "class"; } // The name of the constructor; for example `Array`, `GeneratorFunction`, // `Number`, `String`, `Boolean` or `MyCustomClass` const className = value.constructor.name; if (typeof className === "string" && className !== "") { return className; } // At this point there's no robust way to get the type of value, // so we use the base implementation. return baseType;}
For checking potentially non-existent variables that would otherwise throw aReferenceError
, usetypeof nonExistentVar === "undefined"
because this behavior cannot be mimicked with custom code.
Specifications
Specification |
---|
ECMAScript® 2026 Language Specification # sec-typeof-operator |