TypeScript, a superset of JavaScript that is loaded with superpowers how many times you wrote something only for you to have a deep to find bug because a variable that was supposed to be a string actually stores a number? TypeScript is a useful tool for avoiding bugs like this, if you were actually working with TypeScript this kind of bug would have been discovered before runtime. But TypeScript provides much more than just this.
TypeScript also allows us to use cool features of JavaScript that is not available on vanilla JavaScript. How??? TypeScript being a super set of JavaScript actually compiles down to JavaScript, it is the TypeScript compiler that gives us all of it's cool features. The TypeScript compiler itself is written in TypeScript and compiled down to JavaScript.
This should give you a basic idea of how important TypeScript can be for the developers. This said, it doesn't mean that using TypeScript is all rosy and doesn't come with any trade offs, however you will find out that using TypeScript has many benefits and it outweighs any potential drawbacks you could encounter while using it.
Installation
Ensure that you have node js installed on your machine first if not head to nodejs website and get the latest version. Open up an empty terminal session and install TypeScript by running npm i typescript -g
to install the typeScript compiler. Note this installs it globally on our machine.
What is TypeScript?
The docs say that "TypeScript is an open-source language which builds on JavaScript, one of the world's most used tools, by adding static type definitions.". Don't let this fool you, this simple aspect of TypeScript is arguably one of it's greatest advantage over JavaScript.
Static Type Definitions in our code provides a way to describe the shape of an object, providing better documentation, and allowing TypeScript to validate that your code is working correctly. That's why bugs like the one described above, are caught while we are writing our code rather than after we deploy it. But if you like me and you are quite lazy writing types can be optional in TypeScript, because type inference allows you to get a lot of power without writing additional code.
Since TypeScript is a superset of JavaScript, valid JavaScript is TypeScript! And this automatically makes you feel at home, we could write plain JavaScript and save it with the .ts
extension. And compile it to JavaScript it would still get the job done.
// Valid JavaScript is Typescript
const name = 'Bruce';
console.log(name)
// adding types
const name: string = 'Burger';
const price: number = 380;
const amount: number = 3
const instock: boolean = true
const burger = { name, price, amount, instock }
console.log(burger)
if you compile this code to JavaScript by running tsc filename.ts
. The typescript compiler will compile this code down to vanilla JavaScript for us and if you inspect it, you will find out that it reads to plain JavaScript.
Types
We saw a basic demonstration of how TypeScript extends JavaScript by adding static types, we can use this advantage and compose unique types for objects. We can explicitly declare the type for a variable or we can let typescript infer the type based on the value we assign the variable
// Explicit Typing
let name: string;
let greetings: string
let age: number;
// Name can only store strings
name = 'sam'
// age can only store numbers
age = 24
// functions can also have types
let greet: (name:string) => string
greet = (name) => `hello ${name}`
// Implicit Typing
let hero = 'Thor'
let amount = 2500
greetings = greet('samson')
age = greet(23) // NOT POSSIBLE
console.log(greetings) // hello samson
But TypeScript is not too restrictive and we can opt of static typing by annotating the variable with the type any. This allows us to assign values of different type to the variable.
Functions are also typed in TypeScript, we annotate the parameters that the functions expects to be of a particular type to ensure that the right kind of values are passed in to it when called. We also specify the return type of the function, If we invoke the function and pass in the correct arguments, TypeScript will automatically infer the return type to any variable we store it in.
let hero: any = 'Thor'
hero = { name: 'Thor'}
hero = true
We can also declare union types or restrict the actual value that a variable can hold.
// Union types
let hero: string | object;
hero = 'Thor'
hero = { name: 'Thor' }
// Restricting Values for variables
let universe: 'DCU' | 'MCU';
// universe can only be DCU or MCU
universe = 'DCU'
// Not Possible
universe = 'Something else';
Since we have been declaring types for simple variables, we can also declare types for objects.
type Hero = {
name: string,
universe: 'DCU' | 'MCU'
}
const superman: Hero = {
name: 'superman',
universe: 'DCU'
}
One of the cool benefits of this typing system is that, our IDE will provide us with rich auto-completion and intellisense. This can help with documentation purposes. rather than use types for Object personally i prefer using interfaces to describe the shape of Classes which in turn affects the Object.
TypeScript supports OOP and has many tools up it's belt that i uses to achieve OOP. You could also go with functional approach or whatever programming paradigm you see fit. Let's touch up Interfaces
Interfaces
We can use types for objects as we did but i prefer using interfaces. Interfaces provides a contract that all clients that implements it must satisfy before it is valid. Interfaces are really great OOP tool in TypeScript.
interface Hero {
name: string,
universe: 'DCU' | 'MCU'
}
const superman: Hero = {
name: 'superman',
universe: 'DCU'
}
One thing with interfaces is that they can implement other interfaces or classes, we can take advantage of this feature when working with external libraries and frameworks, by extending our interfaces to implement other interfaces.
interface Human {
name: string,
gender: string
}
interface Hero implements Human {
powers: string[],
uninverse: 'DCU' | 'MCU'
}
// ALl heroes must have the same
// properties as humans
If you observed, the powers
properties on a hero is an array, but we add the string type before the array, this tells TypeScript that the powers property is an array of strings, we can also have arrays of any type. If we want more control over what element is in what position in an array the we could use a tuple.
Arrays
Arrays can be typed such that it only a specific type of value or restricted types of values can be stored inside the array. We can have an array of strings or numbers. Even better we can have an array of both strings and numbers.
// array of numbers;
let nums: number[];
let heroes = Hero[];
let mixedArr: string[] | number[];
nums = [1, 3, 5, 7] // Valid
mixedArr = ['sam', 200, 23, 'foo'] // Valid
nums = ['sam', false] // Not possible
mixedArr = [false, { hero: 'supes'}] // Not possible
Tuples are arrays where each index in the array is typed and cannot store a value whose type do not match the type we specified for that index. Tuples are useful when we use spread operators.
// TUPLES
let tup : [string, hero, number];
tup = ['sam', superman, 23];
We have barely touched the features of TypeScript and what we can do with it. But this is a friendly intro and not to scare you. We will look more in depth about the features of TypeScript and what we can do with it.
CLI Commands
To compile your TypeScript code to JavaScript, just run tsc ./file_name
, file_name should be the name of the file you are trying to compile to JavaScript. If there are no errors, TypeScript will sipt out a JavaScript version of your TypeScript code, even if there are certain bugs in your code it will still spit out the compiled code.
One cool thing with working with TypeScript is that we can customize the behavior of the compiler as we see fit, we can either do this in the command line or through a tsconfig.json
file. The config file is the best way to do this because there is a handful of compiler options that we can customize.
To compile your code whenever you save a change you can run tsc --w
and this will compile your file in watch mode, anytime there is a change to the source code the TypeScript compiler will automatically compile the code again. To generate a blank config file run tsc --init
and TypeScript will give us a blank tsconfig.json
file.
To get a run down of all the compiler options run tsc --all
and it will print all compiler options in your command line . To throw of the version of TypeScript you have installed in your computer run tsc --version
. There is a handful of more CLI commands we can but discuss here and that fits into it's own article
Hope you enjoyed this and also found it useful, feel free to leave a comment below. I will be making a series of articles about TypeScript so stay tuned.
Top comments (0)