Learn about the primitive types in JavaScript, how type coercion works and a better solution to working with types in JavaScript.
All programming languages have built-in types. They’re the building blocks that help us to structure our code and create new applications, frameworks, libraries, etc. Also, these built-in types differ from one language to another. We have different languages for different purposes; each language has a different way of programming and it’s used for a specific use case.
Learning a programming language isn’t an easy task. When you already know how to program in a language, and want to learn another language, that’s a hard challenge as well. The ways and concepts that you have in mind from your previous and main programming language can hinder your process of learning a new one.
JavaScript has become the most-used programming language in the world for a few reasons. One of the most important factors that we can list is that JavaScript is very easy to get started in. Beginners can start to write JavaScript code without too much fuss. For developers who already have experience with another programming language, JavaScript gets easier and turns into a language where everything is possible.
Dynamically vs. Statically
There are two main differences between dynamically typed and statically typed languages:
- Dynamically typed languages perform type checking at runtime.
- Statically typed languages perform type checking at compile time.
Statically typed languages require you to declare the data types of your variables. If you’ve ever used Java or any other statically typed language, you know that we should declare first the type of our variable, like this:
int time = 10;
char name = 'Leonardo';
If we don’t specify the data type of the variable in our statically typed language, it will throw us an error. In this example, we simply defined the time data type as int
and name as a char
.
Another reason JavaScript became so famous worldwide is because it’s a dynamically and weakly typed language at the same time. A weakly typed language is a language where the variables don’t need to be bound to a specific data type.
It’s a very simple, flexible, funny and sometimes tricky programming language. In dynamically typed languages like JavaScript, we don’t need to specify the data types of our variables.
const time = 10;
const name = 'Leonardo';
Dynamically typed languages can compile your code even when there are errors that can crash your application and result in a running problem. Statically typed languages will not allow compiling until all the errors of your code are fixed.
Dynamically typed languages are very flexible and can definitely save us a lot of time when writing our applications. It’s easier to understand the code, we can build faster, etc.
For being flexible, sometimes dynamically typed languages, such as JavaScript, can lead us to some errors at runtime that we don’t catch at first.
3 - 1 // -> 2
3 + 1 // -> 4
'3' - 1 // -> 2
'3' + 1 // -> '31'
We literally have a large GitHub repository called wtfjs with a lot of different strange and tricky errors in JavaScript.
Knowing exactly how all the primitive types of JavaScript work is essential to avoiding these tricky errors in your applications.
Primitive Types
JavaScript is essentially a dynamically typed language. Sometimes it might sound like JavaScript does not have types, and that’s fundamentally incorrect.
When we talk about types in JavaScript, it might mean something very different than when we are talking about types in statically typed languages.
A type provides a set of values from which an expression may take its values, and in JavaScript, we have a few primitive types:
- string
- number
- undefined
- null
- boolean
- symbol
These primitive types are the building blocks of JavaScript—they are the types behind all of our applications.
Everything that’s not a primitive type in JavaScript is an object. Despite what many people might think, objects are not primitive types in JavaScript. We can list a lot of differences between primitive types and objects, but one of the most important is that primitive types are immutable, and an object can only have an immutable reference and their values can change over time.
Every JavaScript developer should know, at least a little bit, how each primitive type works and its intrinsic behavior. It will help to familiarize you with all the different types that we have in the language and when to use each primitive type correctly.
One of the reasons we can have many errors in JavaScript is that as the language is a dynamically and weakly typed language at the same time, it’s hard to predict and assure the variable’s type. Every time we try to get the value of something, it might have changed, as well as the data type.
Type Coercion
Type coercion is a process in JavaScript of converting a value from one type to another. Any type in JavaScript, primitive or object, can be converted into another type.
That’s one of the reasons why JavaScript can be so tricky sometimes. We are using a variable, and by mistake, we might change the data type of this variable to another without noticing it.
There are two types of type coercion: implicit and explicit.
Imagine that you have a string
of value 10
and you want to treat it like a number
. To do so, first, you need to convert (coerce) the value from a string
to a number
. The explicit type of coercion happens when you want to convert a type to another.
let myNumber = 1;
let finalStr = myNumber.toString()
Implicit type coercion usually happens when you apply operators to values of different types. Most of the time implicit coercion is triggered by mistake.
null + {}
Have you ever wondered why there are two different operations for comparisons in JavaScript? We have the ==
and the ===
to make comparisons, and most developers who are starting to learn JavaScript struggle to understand the differences between them.
The ==
operator in some cases might trigger type coercion in JavaScript. Imagine that you have the 20 == "20"
expression and you want to return the result. JavaScript will convert them into the same data type so the comparison can be done.
The ===
does not trigger type coercion in JavaScript, and most of the time it’s the operator that you want to use to compare types. Using this operator, no type of coercion will take place and you can work in a better way with types in JavaScript.
A Better Solution
TypeScript is a superset of JavaScript that adds static typing to the language. It helps to better structure your code, highlight unexpected behavior in your code and reduce the chance of unexpected bugs.
Some people might think that TypeScript is a totally different language from JavaScript and to learn it will demand time, and that’s totally wrong. When you’re running TypeScript code, what happens is that you’re running JavaScript and all the features that it has, TypeScript is just assuring that the types that you’re using are consistently assigned.
Imagine that you want to create a variable called name and want to assure that this variable will be a string no matter what. You can define the type of your variable by simply doing that:
let name: string = "Rose";
If you try to assign a new value to the name variable that’s different from a string, TypeScript will show you an error.
TypeScript also works with type inference—you don’t need to assign the type of the variable in cases you don’t want to. It will automatically use the value as its type.
let name = "Rose";
// let name: string
When you have something more complex in your application, such as a variable that can have different values, you create complex types. You can use union types for that, for example:
type Modal = 'open' | 'close';
That’s only one of the basics of TypeScript, to show how this superset of JavaScript can help you to build more robust and structured code. You will only notice the difference and the benefits of TypeScript when you first use it.
According to the Stack Overflow Survey 2020, TypeScript is a more loved language than JavaScript. TypeScript is very widely used in a lot of different projects and applications nowadays. It’s definitely helping developers to spot errors before running the code, allowing them to create more strongly typed and safe JavaScript code and improving the developer experience.
Conclusion
Everything in JavaScript is either a primitive type or an object. Knowing how to work with types in JavaScript can be a really tricky task. Sometimes it can lead us to make some unexpected errors and create side-effect behaviors in our applications.
We learned about the differences between dynamically and statically typed languages and about type coercion, a process in JavaScript of converting one type to another type that works under the hood. A good solution to solve the unexpected errors of types in JavaScript might be to use TypeScript, a superset of JavaScript that adds static typing to the language.
Keep Reading
Check out these posts to learn more about some key JavaScript fundamentals
- Stack and Queue in JavaScript
- Immutability in JavaScript
- Master these JavaScript Fundamentals to Land Your Next Job