Photo by Mr Cup / Fabien Barral on Unsplash
Specifically, there are two instances when typeof returns “object” in an unexpected way, and this makes type checking a little unusual.
Photo by Alex Read on Unsplash
- object (meaning null)
- object (meaning any object, including arrays)
Next, I explain when to expect each response from typeof in detail.
Photo by Julia Margeth Theuer on Unsplash
Referencing undeclared variables usually results in a ReferenceError, except when using the typeof keyword.
The typeof undefined is the string “undefined” ? and undefined is a falsy value that is loosely equal to null but not to other falsy values.
Thus, if typeof says a value is “undefined”, then it is a safe bet to assume that value is actually undefined ? meaning it was not declared, declared but never assigned a value, or declared and assigned the value of undefined.
Photo by Samuel Zeller on Unsplash
Object (meaning null)
That means that checking for null cannot be performed using typeof.
However, null checking is pretty easy using the strict equality operator (===) to check that the value is indeed null, as in maybeNull===null.
Useful things to know about null
- The value null is falsy (evaluates to false in a conditional).
- The values null and undefined are only loosely equal to each other.
- Neither null nor undefined are equal to other falsy values.
This means that checking for null using the loose equality (==) operator will capture both null and undefined values, which can be useful:
Often, an undefined value means the same thing as a null value ? the absence of a value, so using == is recommended to check for null.
On the other hand, checking for null can be performed easily with the strict equality === operator.
Or one can check by knowing that since the empty object is truthy (evaluates to Boolean true in a conditional), null is the only falsy object.
Photo by Obi Onyeador on Unsplash
Checking for Boolean values is easy ? they are going to be either true or false, and the typeof a boolean returns “boolean”:
Photo by Andrik Langfield on Unsplash
Photo by Kai Gradert on Unsplash
Checking for the primitive type BigInt works as expected; typeof for supported browsers will return “bigint”:
?There is a good chance that BigInt will be part of ECMAScript 2019 or 2020.? ? Ralph?s Blog
Photo by Sagar Dani on Unsplash
It sure is nice when things work like they should when programming!
Photo by Mr Cup / Fabien Barral on Unsplash
?A symbol value may be used as an identifier for object properties; this is the data type?s only purpose.? ? MDN web docs
As one would expect, the typeof Symbol() is indeed “symbol”:
Photo by Shahadat Shemul on Unsplash
Functions are easily checked for using the typeof keyword, which works entirely as expected by returning “function”:
Photo by Dane Deaner on Unsplash
Object (Meaning Object or Array)
ECMAScript 5 introduced an Array.isArray() method to check for an array, since typeof will not be able to tell arrays from other objects.
I demonstrates how to check the type of objects and arrays in this code:
Author Moon describes that method in more detail in Better Programming:
A deeper explanation of [object Object]
Similarly, the helper method Array.isArray() or the keyword instanceof can be used to check for arrays or any type of object, respectively.
Photo by Amador Loureiro on Unsplash
Watch Out for the ?Gotcha!?
The object wrappers for Boolean, number, and string will break typeof and result in “object” instead of “boolean”, “number”, or “string”.
Why do these object wrappers exist if they should not be called explicitly?
Since that happens automatically, there is no need for creating an explicit wrapper object, as it will only break typeof, as shown above.
Photo by Midas Hofstra on Unsplash
One More Reason to Not Use Wrapper Objects
And the behavior only actually changes when the new keyword is used with the object wrapper call, as is shown in the following example:
Photo by Marcus dePaula on Unsplash
Wait, What About Host Objects?
Host objects are implementation-dependent, meaning they are supplied by the local run-time environment.
For example, the window object is supplied by the browser-environment supplies, while a node.js environment supplies other host objects.
This means that the typeof keyword is also implementation-dependent, at least in the case of host objects.
That being said, modern implementations are probably going to return ?object? as the typeof host objects. For example:
Photo by Hannes Wolf on Unsplash
Are Static Types the Future?
Using TypeScript or Flow definitely has some advantages and can prevent bugs, but at the cost of learning and implementing another tool.
Photo by Samuel Ramos on Unsplash
The Wrap Up
On the other hand, Array, Date, and Regular Expressions are native objects that are not differentiated from each other by typeof ? they all return “object” ? as does null, unexpectedly (in a well-known bug).
In short, typeof is an imperfect but powerful tool to check a value?s type.
Photo by Raphael Schaller on Unsplash
- Hugo Di Francesco explores checking for arrays at Code with Hugo:
We’ve all stumbled on a web page that just doesn’t work. You know the type: the links aren’t clickable, the scrolling?
- The static type checker Flow has a similar typeof keyword, but the version in Flow is more powerful according to the official Flow docs:
Typeof Types | Flow
Getting the internal type of a value
Photo by Susan Yin on Unsplash