• Social

An overview of TypeScript

TypeScript is a tool used to help improve the maintainability of your JavaScript code by allowing you to specify the type of data that should be used in your variables and functions, and then highlighting the times when when you have gone astray. Using TypeScript during your development, helps find and prevent bugs and also makes code more readable and descriptive during your development.

The first feature it includes is Static Type Checking. What this means is that you can specify the Type of information you expect in your functions, e.g. a string. If you were to add a number, and TypeScript was expecting a String, it would throw you an error. TypeScript also gives us Classes to work with. This isn’t as big a deal now what with ES6 having them built in, but before ES6, it was a big deal.

In the same way that Sass needs to be compiled to CSS, TypeScript needs to be compiled to JavaScript. This can be done using Node and the package TypeScript Compiler (shock!). The official documents provide a great introduction into setting it up for you to follow along with the below. It’s worth mentioning at this point that you should have good knowledge in JavaScript and JavaScript classes to fully follow along with the below (I wouldn’t want people reading this and getting frustrated if they didn’t pick it up!)

Defining Data Types in variables

The first feature of TypeScript is that it allows you to define the type of data a variable should be. The below code highlights the different types you can use and if you run the below code with your javascript compiler  you will see that it does not flag any issues because the defined types have all been adhered too. You will see you can require variables to be strings, numbers, booleans, arrays, number array, mixed arrays (using tuple), undefined or any of the above (any).

[pastacode lang=”javascript” manual=”let%20myString%3A%20string%0Alet%20myNum%3A%20number%0Alet%20myBool%3A%20boolean%0Alet%20anyVar%3A%20any%0A%0A%2F%2F%20array%20of%20strings%2C%20array%20of%20numbers%2C%20array%20of%20booleans.%0Alet%20strArr%3A%20string%5B%5D%20%2F%2F%20has%20to%20be%20an%20array%20of%20strings%0Alet%20numArr%3A%20number%5B%5D%0Alet%20boolArr%3A%20boolean%5B%5D%0A%0A%2F%2F%20Note%20you%20can%20also%20write%20the%20above%20as%20follows%20but%20I%20prefer%20the%20above%0A%2F%2F%20let%20sttArry%3A%20Array%3Cstring%3E%0A%0A%2F%2F%20Tuple%20means%20it%20must%20match%20the%20given%20array%0Alet%20strNumTuple%3A%20%5Bstring%2C%20number%5D%0A%0A%2F%2F%20Void%20%0A%0A%0AmyString%20%3D%20%22Hello%22%20%2B%20%22%20World%22%0AmyNum%20%3D%202.8%0AmyBool%20%3D%20true%0AanyVar%20%3D%20%22Whatever%20type%20you%20want%22%0A%0AstrArr%20%3D%20%5B’first%20string’%2C%20’second%20string’%5D%0AnumArr%20%3D%20%5B1%2C%202%2C%203%5D%0AboolArr%20%3D%20%5Btrue%2C%20false%2C%20true%5D%0AstrNumTuple%20%3D%20%5B’Hello’%2C%201%5D%20%2F%2F%20%5B’Hello%2C%201%2C%202%2C%203%5D%20would%20also%20work%20as%20only%20need%20to%20pass%20initial%20checks.%0A%0A%0Aconsole.log(myString%2C%20myNum%2C%20myBool%2C%20anyVar%2C%20strArr%2C%20numArr%2C%20boolArr%2C%20strNumTuple)” message=”” highlight=”” provider=”manual”/]

Defining Data Types in functions

The next useful feature of TypeScript are it’s use with functions. The below code demonstrates how you can define the type of data you want a function parameter to be, and also the type of data you want it to return. Note in the below code the use of the question mark which means that the parameter is optional. Although, it’s not strictly TypeScript the function, it’s also good practice to cover different types of data used in the parameters. In the example, we test for the typeOf data and then act accordingly.

[pastacode lang=”javascript” manual=”%2F%2F%20the%20arguments%20have%20to%20be%20numbers%20as%20does%20the%20return%20value%0Afunction%20getSum(num1%3A%20number%2C%20num2%3A%20number)%3A%20number%20%7B%0A%20%20%20%20return%20num1%20%2B%20num2%0A%7D%0A%0A%2F%2F%20console.log(getSum(1%2C%203))%0A%0A%2F%2F%20the%20below%20code%20allows%20for%20someone%20to%20add%20a%20string%20or%20number!%0Alet%20getSum2%20%3D%20function%20(num1%3A%20any%2C%20num2%3A%20any)%3A%20number%20%7B%0A%20%20%20%20if%20(typeof%20num1%20%3D%3D%20’string’)%20%7B%0A%20%20%20%20%20%20%20%20num1%20%3D%20parseInt(num1)%3B%0A%20%20%20%20%7D%0A%20%20%20%20if%20(typeof%20num2%20%3D%3D%20’string’)%20%7B%0A%20%20%20%20%20%20%20%20num2%20%3D%20parseInt(num2)%3B%0A%20%20%20%20%7D%0A%20%20%20%20return%20num1%20%2B%20num2%3B%0A%7D%0A%0A%2F%2F%20getSum2(‘2’%2C%202)%0A%0Afunction%20getName(firstName%3A%20string%2C%20lastName%3F%3A%20string)%3A%20string%20%7B%0A%20%20%20%20if%20(lastName%20%3D%3D%20undefined)%20%7B%0A%20%20%20%20%20%20%20%20return%20firstName%3B%0A%20%20%20%20%7D%0A%20%20%20%20return%20firstName%20%2B%20’%20’%20%2B%20lastName%3B%0A%7D%0A%0Aconsole.log(getName(‘John’%2C%20’Doe’))%20%2F%2F%20The%20question%20mark%20means%20lastName%20is%20optional!” message=”” highlight=”” provider=”manual”/]

Interfaces

In the same way we can write let myString: string; we can also use something called an interface, which is essentially the allowed data types of the key values. The below example should help clarify things, whereby you are specifying the showTodo function that the parameter must be an object with a title and text key that should both be strings.

[pastacode lang=”javascript” manual=”interface%20Todo%20%7B%0A%20%20%20%20title%3A%20string%2C%0A%20%20%20%20text%3A%20string%0A%7D%0A%0Afunction%20showTodo(todo%3A%20Todo)%20%7B%0A%20%20%20%20console.log(todo.title%20%2B%20%22%3A%20%22%20%2B%20todo.text)%0A%7D%0Alet%20myTodo%20%3D%20%7B%20title%3A%20%22trash%22%2C%20text%3A%20%22take%20out%20trash%22%20%7D%0A%0AshowTodo(myTodo)” message=”” highlight=”” provider=”manual”/]

Classes

These are a feature that are now baked into ES6 and so if you’ve used ES6 classes… well then these are nothing new! The code below starts by defining an interface, which sets out the keys and methods that the class must have. We then create a new class called User which implements the userInterface we have just specified. The User class, starts by defining all the keys that the class can take. Notice the public, private and protected specifications which will change the closure of the keys in children classes.

The constructor function is baked into classes and is run when a new User class is created. It sets the keys to the parameters that are handed to it.  We can then use this class by creating a new user called Tom with all the relevant data.

We then want to add member functionality to our software, whereby users can become members. To do this, we can use a feature of classes called extends which means that the Member class will inherit all of the methods and keys of the parent User class but allow us to add new methods and keys on top. We add a new key called ID, because in our imaginary system, Members need an ID but Users don’t. You will notice in the Member class, we can use the super function, another feature of classes, which means it will use the parent class keys (name, email, age). The Member class also needs a payInvoice function and so we can use the parents method by calling it with super.

[pastacode lang=”javascript” manual=”interface%20UserInterface%20%7B%0A%20%20%20%20name%3A%20string%2C%0A%20%20%20%20email%3A%20string%2C%0A%20%20%20%20age%3A%20number%2C%0A%20%20%20%20register()%2C%0A%20%20%20%20payInvoice()%0A%7D%0A%0Aclass%20User%20implements%20UserInterface%20%7B%0A%0A%20%20%20%20name%3A%20string%3B%0A%20%20%20%20age%3A%20number%3B%0A%20%20%20%20email%3A%20string%3B%20%2F%2F%20can’t%20access%20from%20outside%20the%20class%0A%20%20%20%20public%20height%3A%20number%3B%20%2F%2F%20can%20access%20from%20outside%20the%20class%20%0A%20%20%20%20protected%20address%3A%20string%3B%20%2F%2F%20can%20access%20if%20the%20class%20inherits%20from%20this%20User%20Class%20(e.g.%20class%20SuperUser%20extends%20User)%0A%20%20%20%20private%20notes%3A%20string%0A%0A%0A%20%20%20%20constructor(name%3A%20string%2C%20email%3A%20string%2C%20age%3A%20number)%20%7B%0A%20%20%20%20%20%20%20%20this.name%20%3D%20name%0A%20%20%20%20%20%20%20%20this.email%20%3D%20email%0A%20%20%20%20%20%20%20%20this.age%20%3D%20age%0A%0A%20%20%20%20%20%20%20%20console.log(‘user%20created%3A%20’%20%2B%20this.name)%0A%20%20%20%20%7D%0A%0A%20%20%20%20register()%20%7B%0A%20%20%20%20%20%20%20%20console.log(this.name%20%2B%20’%20is%20now%20registered’)%0A%20%20%20%20%7D%0A%20%20%20%20payInvoice()%20%7B%0A%20%20%20%20%20%20%20%20console.log(this.name%20%2B%20’%20has%20paid%20his%20invoice’)%0A%20%20%20%20%7D%0A%7D%0A%0A%2F%2F%20this%20will%20throw%20a%20notification%20in%20typescript%20and%20say%20that%20age%20is%20protected%0Alet%20Tom%20%3D%20new%20User(‘Tom’%2C%20’hello%40tomhoadley.co.uk’%2C%2028)%0A%0Aconsole.log(Tom.age)%0A%0A%2F%2F%20extending%20the%20user%20class%0Aclass%20Member%20extends%20User%20%7B%0A%20%20%20%20id%3A%20number%0A%0A%20%20%20%20constructor(id%3A%20number%2C%20name%3A%20string%2C%20email%3A%20string%2C%20age%3A%20number)%20%7B%0A%20%20%20%20%20%20%20%20%2F%2F%20need%20to%20call%20super%20on%20children%20classes.%0A%20%20%20%20%20%20%20%20super(name%2C%20email%2C%20age)%0A%20%20%20%20%20%20%20%20this.id%20%3D%20id%0A%20%20%20%20%7D%0A%0A%20%20%20%20payInvoice()%20%7B%0A%20%20%20%20%20%20%20%20super.payInvoice()%0A%20%20%20%20%7D%0A%7D%0A%0Alet%20bob%3A%20User%20%3D%20new%20Member(1%2C%20’Bob%20Smith’%2C%20%22bob%40gmail.com%22%2C%2022)%0A%0Abob.payInvoice()” message=”” highlight=”” provider=”manual”/]

Although the above is a slight divergence into classes rather than TypeScript, it is helpful to see how classes and TypeScript can work together to define the types of data that your code requires.

Again, this is useful for the maintainability of good software as it flags errors clearly as you build your code.