Typescript and JavaScript - Two Sides of the Same Coin
We briefly explore the relationship between JavaScript and Typescript and why understanding both Typescript and JavaScript.
The first draft of this issue was written almost a year ago, in a hotel room in Amsterdam. I didn’t think I was going to be publishing, but I thought why not? Any, I digress, I hope you are going to enjoy it.
For a while now, I have been to write an issue that explores the relationship between Typescript and Javascript. While Javascript can exist without Typescript, Typescript can’t (as of the time of writing this).
As web developers, understanding Javascript is vital to developing better mental models for working with Typescript and building kick-ass applications.
The key difference between Typescript and Javascript is the existence of static types. Typescript has placed itself as Javascript but with static types. Even visiting their website, it’s right there with bold and large text.
Typescript has evolved to strive for feature parity with Javascript, but this wasn’t always the case (ahem, decorators and enums anyone).
By providing only the typing system, means adding Typescript to your project should have zero (almost, if you use enums) runtime impact. This is because, when Typescript is compiled, all the types are stripped away (after the useful tasks of type-checking) and you are left with plain old Javascript.
Every Typescript Develeper is a Javascript Developer. Typescript is just Javascript with Types - me 🤦🏾 (2024)
Understanding Typescript is just one side of the equation, where we get to learn how our code behaves up to the compilation/transpilation process. And this is where understanding Javascript is also important.
“By defining our Types, we declare our intentions and Typescript checks whether our code matches our intention. This can be very useful for reducing a whole class of bugs.”
This means it’s important for us to know the behavior to expect from our application, during the runtime. This means understanding Javascript and its peculiarity. For those of us who have been around for a while, we may have come across the famous banana meme:
("b" + "a" + + "a" + "a").toLowerCase()
The expression above results with the string banana, as shown below (you can try it in your browser right now):
The trick is that when you try to sum a string, with a number, it results in the NaN value, which is a global value that represents not a number in Javascript, hence where the NaN comes from in our expression, to complete baNaNa. Even the following expression will result in banana
as the value of the string.
("b" + "a" + + "not a banana" + "a").toLowerCase()
As shown below:
The above is fun and games, but goes to show you about things you can get away with in Javascript. This can be problematic, as you don’t want to make the mistake of summing strings and numbers when you meant numbers. And these are some of the problems that Typescript looks to address.
I know you may be wondering where I am heading with this, but let’s explore the typing system:
The Typing System
In languages, programming languages, there are multiple ways in which we can categorize a language typing system, which allows us to make sense of the Typing system, giving us a glimpse into the behavior of a language when both writing code or our code is running.
Understanding the typing system of the language we are using can help us add some important guardrails to prevent bugs we can foresee.
There are two broad ways of looking at a language Type system:
Static Typing Vs Dynamic Typing
In this kind of type system classification, the variable types are either static, meaning that the type of a variable is known from when the beginning, at the point it’s defined (whether explicitly, or implicitly - think of type inference here). While in a Dynamic Typing System, the variables are assigned their types at runtime, the concept.
In static typing, the language requires types to be known upfront and during the build/compile step, it will type check your code to ensure type safety while dynamic typed languages do not.
Strongly Typed vs Weakly Typed
On top of being either static or dynamic, the type system of a language can either be strong or weak. A strong typing system doesn’t allow for the type of a variable to be changed when it’s assigned, either statically or dynamically, while a weak typing system, will allow the variables’ type to change, and can take different types as the variables get data assigned to it.
With weakly typed languages, variable type changes implicitly during their life-cycle while in strongly typed, this doesn’t happen.
Where do Javascript and Typescript fall in this category?
As we have said previously, Javascript and Typescript are tied at the hip, while Typescript provides a static typing system to Javascript, just because Typescript doesn’t exist at runtime, it inherently borrows some of the characteristics of the Javascript typing system - the runtime behavior. Web developers working with Typescript need to understand this.
When you work with Typescript, you are by extension working with Javascript, and understanding Javascript is vital.
But before I can go on and say, that Typescript is good, and javascript bad (oh, I know, no one likes hyperbole), let’s first look at them as independent languages, which is kind of hard when one compiles into the other one.
Typescript is statically typed - your variable types, even when using any have to be assigned when you define the variable - this can be done either explicitly or implicitly, relying on the inference system, but the end goal is known upfront.
You are also not allowed to change the type of variable once annotated. A few things to keep in mind here is the any
type, which can be assigned to any variable and vice versa - I would encourage you to disable implicit any in tsconfig.json
and in such cases, provide annotations for variables where Typescript can’t infer types explicitly, or manually.
On the other hand, Javascript is dynamically typed and weakly typed, meaning a variable’s Type is determined at runtime based on the value it’s assigned and that type can change during the lifetime of a variable.
Remember when I said, Typescript borrows some of the characteristics of the Javascript type system? The reason I said this is because, When we compile Typescript to Javascript, we lose everything and our runtime Type system is that of Javascript rather than Typescript's desired behavior.
It is important to know and understand this and why you cannot trust any data from external sources - outside your code. User input data and API data should be validated to ensure that you are working with data that matches your expectations.
And I would highly discourage using type assertions (another topic, for a future All Things Typescript issue), and instead rely on schema validation libraries like Zod and Valibot for this, which brings data validation to Javascript, at runtime.
Why do we need Typescript?
I know what you are wondering now, why do we need Typescript? Let's try and answer now by looking at what Typescript brings to the table.
Typescript adds a typing system for Javascript, allowing you to define the shape of your data and Typescript will type-check your code against the types. This ensures
By defining typescript, we are defining our intention or contract and then when we make a mistake, like passing the wrong type of data to a function, typescript prevents us from making that mistake.
This eliminates a whole class of bugs and is very beneficial, as most of the bugs can be caught at compile time before you even compile to Javascript. I find out that most of the bugs I make are typos which can be very devastating and Typescript helps guard against this very well.
Other benefits of Typescript, include auto-completion, which we get because we define the shape of our data and make the developer experience (DX) much better.
Conclusion
In this issue of All Things Typescript, I superficially explored the relationship between Javascript and Typescript, with the goal being to help developers improve their Typescript skills.
Both languages, are tied to the hip, Typescript is a superset of Javascript and apart from the typing system, Typescript looks to be TC39 compliant, meaning feature parity with Javascript.
That's it for this issue and thank you for getting this far. If you enjoyed this article and would like to support my work, please share and like this issue and consider sharing All Things Typescript with friends and colleagues.
Did you know you can also hire me to coach your team and help them level up their Typescript game? If this sounds interesting to you, please consider getting in touch and we can work out something.
And until next time, please keep on learning.