Understanding Typeof in JavaScript

As the name implies, the typeof keyword is used to determine the types of data. This is one of the most common JS keywords found in JS apps. Knowing the type of data you are working on is often found crucial. In this post, we will look into the typeof keyword in JS.

POSTly is a web-based API tool that allows for fast testing of your APIs (REST, GraphQL). Check it out here:

typeof usage

typeof data

The data is the variable we want to get the data type. Notice there is no parenthesis just the typeof keyword followed by a space and the data.

// typeof.js
let num = 90
l(typeof num)

num is a number so typeof will return a number string:

number

Let’s see other examples:

// typeof.js
const l = console.log
let str = "str"
let num = 90
let undef = undefined
let nul = null
let obj = { d: 90 }
let arr = [90]
function func() {}
let sym = Symbol("sym")
let bool = true
function showtype(data) {
l(typeof data)
}
showtype(str)
showtype(num)
showtype(undef)
showtype(nul)
showtype(obj)
showtype(arr)
showtype(func)
showtype(bool)
showtype(sym)

Output:

$ node typeof
string
number
undefined
object
object
object
function
boolean
symbol

What it returns

typeof keyword returns one of the following data types:

  • string
  • number
  • undefined
  • object
  • function
  • boolean
  • symbol
  • bigint

string: Anything between “” is a string in JS:

let str = "str"

The variable str is a string data type. So typeof str will return string.

number: This represents numbers 0~9. typeof against a Number type will return “number”.

le num = 90
l(typeof num)

Output:

$ node typeof
number

The NaN also returns number contrary to its meaning NaN => Not a Number

let nan = NaN
l(typeof nan)

Output:

$ node typeof
number

This is very confusing, how can a value that is “Not a Number” eval to a number? To check for NaN, it’s obvious we can’t use the typeof keyword, we will use the isNaN function.

let nan = NaN
l(typeof nan)
l(isNaN(nan))

Output:

number
true

undefined This is returned when a variable has no value set yet or has an undefined set explicitly.

let undef
l(undef)
let undef1 = undefined
l(undef1)

When typeof is set against an undefined variable it will return “undefined”:

let undef
l(under)
let undef1 = undefined
l(undef1)
l(typeof undef)
l(typeof undef1)

Output:

$ node typeof
undefined
undefined

This is good, so we can check for undefined values using the typeof keyword.

object: This is a bit tricky. Many variable types return objects.

null, array, object

let nul = null
let obj = { d: 90 }
let arr = [90]
l(typeof nul)
l(typeof obj)
l(typeof arr)

Output:

$ node typeof
object
object
object

We can see that all of them return the object as type. With this, we cannot test null and array with the typeof operator.

But, null being an object. That’s mind-boggling. History told us this was an unfixed bug in Js and it has haunted us p to this day. Fixing the bug now, we crash billions of JS codebase and apps. So we have to live with it.

To check for null, we will use either the loose equality or strict equality, in both, the == resolves to true to itself:

let nul = nulll(nul == null)
l(nul === null)

Output:

true
true

function: functions resolve to “function” under typeof. Pretty easy. regular functions, expression or arrow functions, and IIFEs all resolve to “function”.

function func() {}
const arrFunc = () => {}
l(typeof func)
l(typeof arrFunc)

Output:

$ node typeof
function
function

boolean: Boolean has two values true or false. These return the boolean type.

let bool = true
l(bool)

Output:

$ node typeof
boolean

So we see its quite easy to check for booleans. Boolean shave truthy and falsy values. All values in JS are truthy except the falsy ones. falsy values are:

  • 0
  • “” (Empty string)
  • NaN
  • false
  • null
  • undefined

symbol: This is used to creating non-clashing names in JS. They are mostly used in creating keys in objects. These return “symbol” string.

let sym = Symbol("sym")
l(typeof sym)

Output:

$ node typeof
symbol

bigint

BigInt is a built-in object that represents numbers between range 2⁵³ — 1. To create a bigint variable type, we append n to the end of an integer literal. bigint is returned when a variable of BigInt is used against typeof:

let bigint = 90n
l(typeof bigint)

Output:

$ node typeof
bigint

typeof and wrapper functions

Using new Boolean, new String, etc breaks the typeof result on them.

If I do this:

let bool = new Boolean(true)

It will no longer return true, it will return an object when its type is checked with typeof

let bool = new Boolean(true)
l(typeof bool)

Output:

$ node typeof
object

These wrapper functions break the data type. Whenever we use wrapper functions on primitives, JS coerces them to objects. We know primitive types do not have properties, they are standalone.

let str = "str"
let num = 90

But if we do this to str:

str.length

We are accessing a property in the primitive, it shouldn’t be so but yet we have a result:

3

JS coerces str primitive to object then have the length property retrieved. On returning the result the str becomes primitive again.

In str.length property, JS did this:

l(new String("str").length)

It wrapped the str in new String() before accessing the length property.

typeof and objects

As we saw above Arrays, null, object, NaN all return “object”. Others concepts, RegExp, Date all return “object”. So we cannot test for Array or any of them using typeof.

Array has Array#isArray(...) that correctly determines a data is an Array.

To check for null you can either

isNull === null

or

!isNull && typeof isNull == "object"

For NaN use isNaN or Number#isNaN API.

For Date, use duck typing:

typeof date.getMonth === "function"

or you can use instanceof but it will return for invalid dates too.

Conclusion

typeof is both a powerful and indeterminate tool in type checking. It kinda has a buggy behavior when dealing with null, NaN, object, Array, Object, etc types. However, it is useful for some primitive types: number, bigint, symbol, undefined, string, boolean.

If you have any questions regarding this or anything I should add, correct or remove, feel free to comment, email or DM me.

Thanks !!!

Get my eBook

I have written an eBook that explains a lot of JavaScript concepts in simpler terms with reference to the EcmaSpec as guide:

Thanks for stopping by my little corner of the web. I think you’ll love my email newsletter about programming advice, tutoring, tech, programming and software development. Just sign up below:

Follow me on Twitter.

Dev Proto

News, articles, and knowledge bank for software developers

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store