Examples
Basic usage
// Numbers typeof 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 numbers typeof Number('shoe') === 'number'; // including values that cannot be type coerced to a number typeof 42n === 'bigint'; // Strings typeof '' === 'string'; typeof 'bla' === 'string'; typeof `template literal` === 'string'; typeof '1' === 'string'; // note that a number within a string is still typeof string typeof (typeof 1) === 'string'; // typeof always returns a string typeof String(1) === 'string'; // String converts anything into a string, safer than toString // Booleans typeof true === 'boolean'; typeof false === 'boolean'; typeof Boolean(1) === 'boolean'; // Boolean() will convert values based on if they're truthy or falsy typeof !!(1) === 'boolean'; // two calls of the ! (logical NOT) operator are equivalent to Boolean() // Symbols typeof Symbol() === 'symbol' typeof Symbol('foo') === 'symbol' typeof Symbol.iterator === 'symbol' // Undefined typeof undefined === 'undefined'; typeof declaredButUndefinedVariable === 'undefined'; typeof undeclaredVariable === 'undefined'; // Objects typeof { a: 1 } === 'object'; // use Array.isArray or Object.prototype.toString.call // to differentiate regular objects from arrays typeof [1, 2, 4] === 'object'; typeof new Date() === 'object'; typeof /regex/ === 'object'; // See Regular expressions section for historical results // The following are confusing, dangerous, and wasteful. Avoid them. typeof new Boolean(true) === 'object'; typeof new Number(1) === 'object'; typeof new String('abc') === 'object'; // Functions typeof function () {} === 'function'; typeof class C {} === 'function'; typeof Math.sin === 'function';
typeof null
// This stands since the beginning of JavaScript typeof null === 'object';
In the first implementation of JavaScript, JavaScript values were represented as a type
tag and a value. The type tag for objects was 0
. null
was
represented as the NULL pointer (0x00
in most platforms). Consequently,
null
had 0
as type tag, hence the typeof
return
value "object"
. (reference)
A fix was proposed for ECMAScript (via an opt-in), but
was rejected.
It would have resulted in typeof null === 'null'
.
Using new operator
// All constructor functions, with the exception of the Function constructor, will always be typeof 'object' const str = new String('String'); const num = new Number(100); typeof str; // It will return 'object' typeof num; // It will return 'object' const func = new Function(); typeof func; // It will return 'function'
Need for parentheses in Syntax
The typeof
operator has higher precedence 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 + ' Wisen'; // 'number Wisen' typeof (someData + ' Wisen'); // 'string'
Regular expressions
Callable regular expressions were a non-standard addition in some browsers.
typeof /s/ === 'function'; // Chrome 1-12 Non-conform to ECMAScript 5.1 typeof /s/ === 'object'; // Firefox 5+ Conform to ECMAScript 5.1
Errors
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.
However, using typeof
on lexical declarations (let
const
, and class
) in the same block before the line of declaration will throw a ReferenceError
. Block scoped variables are in a temporal dead zone from the start of the block until the initialization is processed, during which it will throw an error if accessed.
typeof undeclaredVariable === 'undefined'; typeof newLetVariable; // ReferenceError typeof newConstVariable; // ReferenceError typeof newClass; // ReferenceError let newLetVariable; const newConstVariable = 'hello'; class newClass{}
Exceptions
All current browsers expose a non-standard host object document.all
with type undefined
.
typeof document.all === 'undefined';
Although the specification allows custom type tags for non-standard exotic objects, it
requires those type tags to be different from the predefined ones. The case of
document.all
having type 'undefined'
is classified in the web
standards as a "willful violation" of the original ECMA JavaScript standard.
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 as
typeof new Date()
, typeof /abc/
, etc.
For greater specificity in checking types, here we present a custom type(value)
function, which mostly mimics the behavior of typeof
, 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 non-existent variables that would otherwise throw
a ReferenceError
, use typeof nonExistentVar === 'undefined'
.