Let's say you are writing TypeScript, when you realize that you need to cast Boolean values into numbers to suit an existing pattern. Not only that—you aren't even sure if you are working with true Booleans or string values!
It is important that we understand the types of values we manipulate in applications. Types can be tricky, but it's nothing we can't handle with a little ✨ JS magic ✨!
Dude, where's my type?
Thankfully, we can use typeof
to identify types quickly. This is a built-in JavaScript operator, so it's ready for you to use right out of the box.
Let's say we want to check the type of a constant:
const foo = false
typeof foo
This returns the type Boolean
.
There are nine possible results when you use typeof
:
Type | Result | Description |
---|---|---|
Boolean | 'boolean' | A binary true or false value |
Number | 'number' | A numerical value |
String | 'string' | A text value |
Symbol | 'symbol' | A unique value often used as an identifier |
BigInt | 'bigint' | An object used with numbers too large for Number |
Function | 'function' | Code that can be called by code other than itself |
Undefined | 'undefined' | Represents an unintentionally absent value |
Null | 'object' | Represents an intentionally absent value |
Object | 'object' | Anything else |
Note that if a value is not primitive, it is considered an Object
. For example, arrays and functions are objects. Oddly enough, Null
values are also considered objects! This is important because we cannot necessarily differentiate between Null
and Object
values using typeof
.
const foo = null
const bar = []
typeof foo // returns 'object'
typeof bar // returns 'object'
Here are a few examples of typeof
in action:
// returns 'boolean'
typeof true
// returns 'string'
typeof 'megafauna'
typeof '99'
// returns 'number'
typeof 99
typeof Math.PI
typeof Infinity
typeof NaN
// returns 'bigint'
typeof 99n
// returns 'symbol'
typeof Symbol('megafauna')
// returns 'function'
typeof function(megaFauna) {}
// returns 'object'
typeof {mega: 'fauna'}
typeof ['mega', 'fauna']
JavaScript type conversions
In JavaScript, "casting" refers to type conversions. Considering we cannot convert Null
or Undefined
values, let's focus on converting the first four: Boolean
, Number
, String
, and Symbol
. We will cover four options for casting types:
String
toString()
Number
Boolean
Number to String
Either use the String
function or toString()
method to cast a string value.
const foo = 99
typeof foo // returns 'number'
String(foo) // returns '99'
typeof String(foo) // returns 'string'
foo.toString() // returns '99'
typeof foo.toString() // returns 'string'
Boolean to String
The same can be used on Boolean values!
const foo = false
typeof foo // returns 'boolean'
String(foo) // 'false'
typeof String(foo) // returns 'string'
foo.toString(foo) // 'false'
typeof foo.toString // returns 'string'
Boolean to Number
While we're on the topic of Booleans, let's consider what it looks like to cast a number instead of a string.
If we stop to think about this, what do we expect to receive? A Boolean
value is binary by design. It is a logical outcome: true or false. It makes sense then that the numerical representation of a binary outcome would be the presence of something (the number 1) or the absence of something (the number 0).
To cast a Number
from a Boolean
, we use the global Number
function:
const foo = false
const bar = true
Number(foo) // 0
typeof Number(foo) // returns 'number'
Number(bar) // 1
typeof Number(bar) // returns 'number'
String to Number
Again, the Number
function is your friend when we are casting numbers from strings, and this is pretty straightforward so long as we have valid numerical characters in our string. As it turns out, spaces included in string values do not need to be cleaned to be compatible with Number
! Although, an empty string will convert to zero.
const foo = '99'
const bar = ' 9.9 '
const baz = ''
Number(foo) // 99
typeof Number(foo) // returns 'number'
Number(bar) // 9.9
typeof Number(bar) // returns 'number'
Number(baz) // 0
typeof Number(baz) // returns 'number'
If your string is an invalid number, Number
will return NaN
, a signifier for "not a number".
Booleans! Booleans! Booleans!
Of the options we covered, probably the most surprising is the Boolean()
method. It tests for presence or absence, and returns a Boolean
accordingly. Because of this, it does not work as most would expect! Here are two shortcuts to keep this straight.
- Using
Boolean()
onfalse
,null
,undefined
,''
,NaN
, or0
will returnfalse
- Using
Boolean()
on everything else will returntrue
What this looks like:
typeof Boolean(false) // returns 'false'
typeof Boolean('false') // returns 'true'
That's right. So, a common mistake is to use this method to create Booleans from strings. Only when we pass in an empty string will we receive a false
value.
A Boolean bonus
In JavaScript, an even easier way to cast booleans is to use the !!
operator! This is functionally equivalent to using Boolean()
. How cool is that?
const foo = 1
typeof !!foo // returns 'true'
Back to the problem at hand
Let's take a look at how we would resolve the issue we encountered in the first place.
Let's say you are writing TypeScript, when you realize that you need to cast Boolean values into numbers to suit an existing pattern. Not only that—you aren't even sure if you are working with true Booleans or string values!
We need to take two steps:
- Identify the type of value we are using (
Boolean
orstring
) - Cast those values into
Number
values
First, we can rely on our trusty typeof
function...
typeof mysteryConst // returns 'Boolean'
...to figure out our next step. Working with a Boolean
, we now just need to apply Number()
:
typeof mysteryConst // returns 'Boolean'
numberConst = Number(mysteryConst)
typeof numberConst // returns 'number'
Now we are in business!