TypeScript is a programming language that’s a superset of JavaScript, which means it understands all of JavaScript’s syntax and capabilities, while adding additional features. TypeScript’s primary value add over JavaScript is static typing. This means that type-checking happens at the time of code compilation. Type-checking is a programming language’s way of confirming that all operations have received the correct type of data to perform the operation. For example, a simple addition operation would expect at least two numbers. If one side of the addition operation is not a number, there might be type checking errors or unexpected behavior. Microsoft developed TypeScript and released it to the public in 2012.
What Is TypeScript Used For?
Is TypeScript Better Than JavaScript?
TypeScript is like a fairy godmother, protecting you, the developer, from running code that’s incorrect or making erroneous assumptions.
JavaScript is a dynamically typed language, which means that JavaScript code can successfully compile even if there are errors that would prevent the code from running correctly, or at all. The type-checking occurs during runtime when you’re actually executing the code, so the code might seem correct in its file, but then crash or cause odd bugs while it’s running.
In contrast, TypeScript type-checking takes place during compile time, and if there are type errors it will not successfully compile, which prevents bad code from going out to be run.
A tangible example might look something like this:
const bakedAlaska = {
insideLayers: {
cake: ‘vanilla’,
iceCream: ‘chocolate’
},
outsideLayers: [’merengue’]
}
const getTotalNumberOfLayers = () => {
return bakedAlaska.insideLayerd.length + bakedAlaska.outsideLayers.length
}
The author of this code has defined a dessert object and a function that intends to calculate the total number of layers in this dessert.
If this is a JavaScript file, this code seems to be straightforward and error-free at a glance. However, the author of the code has made two errors inside the function.
The first is that length
is not a property on an object and will always return undefined
. The second is that the insideLayers
property of the bakedAlaska
is misspelled as insideLayerd
(layerd vs. layers).
When you run this code, it will actually crash with the error: Cannot read property ‘length’ of undefined.
If this is instead being written in a TypeScript file, the code editor will use the power that TypeScript gives it through static typing and show a helpful error on the misspelled object property.
Property ‘insideLayerd’ does not exist on type ‘{ insideLayers: { cake: string; iceCream: string; }; outsideLayers: string[]; }’. Did you mean ‘insideLayers’?.
Most code editors, such as VSCode, will even offer a quick fix option that will update the spelling. Once that error is fixed, a new one appears.
Property ‘length’ does not exist on type ‘{ cake: string; iceCream: string; }’
.
TypeScript infers the type of object referenced by bakedAlaska.insideLayers
and correctly suggests an object like this would not have a length
property on it.
How Does TypeScript Work?
Browsers and most other platforms like node
that run JavaScript do not have native support for TypeScript. TypeScript comes with a compiler called tsc
which will take your beautifully crafted TypeScript files, strip all the extras and convert them into JavaScript so that the browser (or whatever platform you’re using) will be able to run your code as if it was JavaScript.
In order to set up tsc
, you’ll need to have a tsconfig.json
file at the root of your project. It will allow you to specify which version of JavaScript to use when converting your TypeScript files, as well as configure additional TypeScript settings.
Why Should I Use TypeScript?
TypeScript can infer types (even if they’re not explicitly defined by the developer) to power type-checking and autocomplete in a code editor. Autocomplete on its own is very powerful and helps to speed up development and enhance the developer experience. The code editor will be able to easily show what properties exist on an object, what type those properties are, auto complete function and variable names, show syntax highlighting, and much more.
Another way TypeScript makes working in a codebase easier, especially if it’s a large and/or shared codebase, is the way code becomes self documenting. For example, in JavaScript we would have to do a bit of guesswork to determine the type of argument expected in the function below (is birthday
a string? A Unix timestamp? number?).
const wishHappyBirthday = (birthday) => {
const today = new Date()
if (today === birthday){
console.log(’Happy birthday!!’)
}
}
Just a note: This function is loosely pseudocode; in reality, we would do some additional parsing of the date object to extract the month and day.
With TypeScript we can specify the argument type instead. With that simple addition of birthday: Date
, we now explicitly know our function is expecting a Date
object even if this is the first time we’re seeing this function. Even better, if we accidentally pass in something that is not a Date
object, TypeScript will flag the error when we call the function, before we’ve even run our code.
const wishHappyBirthday = (birthday: Date) => {
const today = new Date()
if (today === birthday){
console.log(’Happy birthday!!’)
}
}
How to Use TypeScript
If you’d like to incorporate TypeScript’s type-checking features into an existing JavaScript project, the TypeScript docs have great suggestions for adding TypeScript features incrementally. The first thing you can do if you’re curious is add the comment // @ts-check
to the top of your JavaScript file. This will allow your editor to use TypeScript’s language processing tools to show you any errors right in your code editor’s file. You might think you have perfect code but TypeScript often catches would-be bugs that a code review won’t.
As you move toward total adoption of TypeScript in your project, you’ll find that, while it’s really quite similar to JavaScript, it’s also a bit more constricting (in a good way!). For example, If you instantiate a variable in JavaScript that is a string (let iceCream = “chocolate”)
, JavaScript will have no problem at all with changing the iceCream
variable to a different type (iceCream = true)
.This can cause unexpected behaviors since it’s essentially impossible to know what to expect when using the iceCream
variable.
TypeScript gives us two options for dealing with this problem. The first is to simply let TypeScript infer the type based on the usage. In the let iceCream = “chocolate”
example, TypeScript will be able to implicitly infer the iceCream
variable should be a string and will not let us later assign a different type to it. The second way is to actually tell TypeScript what type the variable should be (let iceCream: string = “chocolate”)
. We explicitly assign a type. In both cases, TypeScript will give us an error if we try to reassign this variable to anything but a string
.
We can even go so far as to constrict the type further:
let iceCream: “chocolate” | “chocolateChipCookieDough” = “chocolate”
Now we’re telling TypeScript that we will only allow these two specific strings to be assigned to the ice cream variable. TypeScript allows us a lot of customization in the realm of types and this is just a fraction of what you can do.
Should I Learn JavaScript or TypeScript?
TypeScript is on 2022’s list of the top 5 programming languages most loved by developers compared to JavaScript, which comes in at number 16. This really gives us a sense of what an improved developer experience TypeScript offers.
That said, no language is perfect and TypeScript does have some drawbacks. Developers familiar with JavaScript might feel at first that it’s a lot more restrictive and requires more boilerplate code. TypeScript can also be difficult to understand when it comes to some of the more advanced use-cases like generics. Don’t let that discourage you, though. Try it out and see what you think!