TypeScript Tutorial: What is, Interface, Enum, Array with Example

What is TypeScript?

TypeScript is a superset of JavaScript. TypeScript is pure object-oriented programming language that supports classes, interfaces, etc. It is an open-source language developed by Microsoft which statically compiles the code to JavaScript. It can easily run in a browser or Nodejs.

All the latest features released for ECMAScript are supported in TypeScript and in addition to it TypeScript has its own object-oriented features like interfaces, ambient declaration, class inheritance, etc. which helps in developing a large application which otherwise would be difficult to do in JavaScript.

How to Download and Install TypeScript

Here is the step by step process to download and install TypeScript:

Step 1) Download and Install Nodejs

Go to the official site of nodejs : https://nodejs.org/en/download/ and download and install nodejs as per your operating system. The detailed instruction on how to download nodejs is available here: https://www.guru99.com/download-install-node-js.html

Step 2) Check Nodejs and npm version

To check if nodejs and npm is installed just check the version in your command prompt.

D:\typeproject>node --version
V10.15.1

D:\typeproject>npm --version
6.4.1

So you have nodejs v10 and npm 6 installed.

Step 3) TypeScript Installation

Create your project directory typeproject/ and run npm init, as shown in the command below:

npm init

Step 4) Start the Installation

Now, we will create package .json which will store the dependencies for our project.

Once done install TypeScript as follows:

npm -g install typescript

The above command will take care of installing TypeScript. Adding “-g” to npm install will install TypeScript globally. The advantage of using -g is that you will be able to use TypeScript tsc command from any directory as it is installed globally. In case you don’t want to install TypeScript globally use below command:

npm --save install typescript

Create src/ folder in your project directory and in src/ folder create TypeScript file test.ts and write your code.

Example : test.ts

function add(x:number, y:number) {
	return x+y;
}

let sum = add(5,10);
console.log(sum);

Compile TypeScript code to Javascript

To compile above code use following command:

If TypeScript is installed globally use below command:

tsc test.ts

If TypeScript is installed local to your project you need to use the path of TypeScript from node_modules as shown:

node_modules/typescript/bin/tsc test.ts

The above command will create a test.js file and will be have code compiled to javascript.

Example : test.js

function add(x, y) {
    return x + y;
}
var sum = add(5, 10);
console.log(sum);

Execute Javascript using Nodejs

In this TypeScript tutorial, we will execute test.js in nodejs as follows:

D:\typeproject\src>node test.js
15

The value consoled is displayed on the execution of test.js

Execute JavaScript in Browser

Example:

<html>
<head></head>
<body>
<script type="text/javascript" src="test.js"></script>
</body>
</html>

Execute Javascript using Nodejs

Compile TypeScript code to Javascript using EcmaScript version

TypeScript supports all the Ecmascript features released, and developers can use the same while coding. But not all the new features support on older browsers, due to which you need to compile javascript to an older version of Ecmascript. TypeScript provides compiler options which can do so.

Example : test.ts

var addnumbers = (a, b) => {
    return a+b;
}

addnumbers(10, 20);

To compile to the ES version of your choice, you can use the target or t option in your command as follows:

tsc --target ES6  test.ts

OR

tsc -t ES6 test.ts

By default, the target is ES3.In case you want to change it, you can use the above command.

At present we will use ES6 in this TypeScript tutorial as the target:

tsc --target ES6  test.ts

test.ts to test.js

var addnumbers = (a, b) => {
    return a+b;
}

addnumbers(10, 20);

The code remains as it is, as the arrow function you have used is a ES6 feature and the same when compiled to ES6 is not changed.

By default the target is ES3 so without target you get test.js as :

var addnumbers = function (a, b) {
    return a + b;
};
addnumbers(10, 20);

So over here, the fat arrow is changed to a normal anonymous function.

Variables in TypeScript

Variables are used to store values, and the value can be a string, number, Boolean, or an expression. When it comes to variables in TypeScript, they are similar to JavaScript. So let’s learn to declare and assign value to variables in TypeScript.

Variables cannot be used in code without defining. To declare a variable you can use

var keyword,

let keyword

const keyword

Working with variables in TypeScript is similar to javascript, and users familiar with javascript will find it very easy. Only variables like let and const are not much used in comparison to var.

Declaring variables using var

Syntax:

var firstname = "Roy";

Let us take a look at few TypeScript examples to understand the working of var keyword and also the scope of variables declared using var keyword.

Example 1:

var  k = 1; // variable k will have a global scope

function test() {
    var c = 1; // variable c is local variable and will be accessible inside function test, it will not be available outside the function.
    return k++;
}

test(); // output as  1
test(); // output as 2
alert(c); // will throw error , Uncaught ReferenceError: c is not defined

Example 2:

var t = 0; // variable t is declared in global scope.
function test() {    
    var t = 10; //variable t is again redeclared inside function with value 10, so here t is local to the function and changes done to it will remain inside the function.
    return t;
}
test(); // will return 10.
console.log(t); // will console 0.

Example 3:

var i = 0;
function test() {
    if (i>0) {
      var t = 1;
    }
    return t;
}

test(); // the value returned will be undefined. The if-block has the variable which gets executed when I> 0. Over here the if-block is not expected but you are still having a reference to the variable t, and it returns undefined, this is because var defined variables once defined inside a function will have reference to it inside the function.  
i++; // here value of i is incremented.
test(); // since i >0 the if block is executed and value returned is 1.

Declaring variables using let

The TypeScript syntax for let is as given below:

Syntax:

let name="Roy";

The working of let variable is almost same as var, but with a small difference and will understand the same using an TypeScript example.

Example:

let i = 1;
function test() {
    if (i>0) {
	  let t = 1;
    }
    return t;
}

test(); // throws an error : Uncaught ReferenceError: t is not defined.

Above TypeScript example throws an error, but the same would have worked fine if it was with the var keyword. Variables using let are available within the block scope declared, for example, the variable t is available only inside the if-block and not to the entire function.

Also if you happen to declare a variable inside any function, or for-loop, while-loop, TypeScript switch block, it will be available to you only inside that block and no reference to it outside the block, and it will throw an error if the variable is used outside the block. This is the main difference between var and let keyword declared variables.

Declaring variables using const

Const means constant variables. They are similar to let variables, with the only difference, is that once a value is assigned to it cannot be changed.

Syntax:

const name;

Example:

const age = "25"; 
age="30"; // will throw an error : Uncaught TypeError: Assignment to constant variable.

So users can use const variables only in cases when they know they don’t have to change the values assigned to it.

Types in TypeScript

TypeScript is a strongly typed language, whereas javascript is not. A variable which has a value defined as a string can be changed to a number without any issues in Javascript. The same is not tolerated in TypeScript. In TypeScript, the type to a variable is defined at the start only and through the execution, it has to maintain the same type any changes to it will lead to a compile-time error during compilation to javascript.

Following are the types :

  • Number
  • String
  • Boolean
  • Any
  • Void

Number

Takes only integers, floats, fractions, etc.

Syntax:

let a :number = 10;
let marks :number = 150;
let price :number = 10.2;

Here are some important methods which can be used on Number types:

toFixed() – it will convert the number to a string and will keep decimal places given to the method.

toString() – this method will convert number to a string.

valueOf() – this method will give back the primitive value of the number.

toPrecision() – this method will format the number to a specified length.

Example : with all String methods

let _num :number = 10.345;
_num.toFixed(2); // "10.35"
_num.valueOf(); // 10.345
_num.toString(); // "10.345"
_num.toPrecision(2); //"10"

String

String: only string values

Syntax:

let str :string = "hello world";

Here are some important methods which can be used on String types:

  • split() – this method will split the string into an array.
  • charAt() – this method will give the first character for the index given.
  • indexOf() – this method will give the position of the first occurrence for the value given to it.
  • Replace () – this method takes 2 strings, first the value to search in the string and if present will replace it will the 2nd one and will give a new string back.
  • Trim () – this method will remove white spaces from both sides of the string.
  • substr() – this method will give a part of the string which will depend on the position given as start and end.
  • substring() – this method will give a part of the string which will depend on the position given as start and end. The character at the end position will be excluded.
  • toUpperCase() -will convert the string to uppercase
  • toLowerCase() – will convert the string to lowercase.

Example:

let _str:string = "Typescript";

_str.charAt(1); // y
_str.split(""); //["T", "y", "p", "e", "s", "c", "r", "i", "p", "t"]
_str.indexOf("s"); //4 , gives -1 is the value does not exist in the string.
_str.replace("Type", "Coffee"); //"Coffeescript"
_str.trim(); //"Typescript"
_str.substr(4, _str.length); //"script"
_str.substring(4, 10); //"script"
_str.toUpperCase();//"TYPESCRIPT"
_str.toLowerCase();//"typescript"

Boolean

Will accept logical values like true, false, 0, and 1.

Syntax:

let bflag :boolean = 1;
let status :boolean = true;

Any

Syntax:

let a :any = 123
a = "hello world"; // changing type will not give any error.

Variables declared using any type can take the variable as a string, number, array, boolean or void. TypeScript will not throw any compile-time error; this is similar to the variables declared in JavaScript. Make use of any type variable only when you aren’t sure about the type of value which will be associated with that variable.

Void

Void type is mostly used as a return type on a function which does not have anything to return.

Syntax:

function testfunc():void{
 //code here
}

TypeScript Array

An Array in TypeScript is a data type wherein you can store multiple values. Let’s learn how to declare and assign values for Array operations in TypeScript.

Since TypeScript is a strongly typed language, you have to tell what will be the data type of the values in an array. Otherwise, it will consider it as of type any.

Declare and Initialize an Array

Syntax:

let nameofthearray : Array<typehere>

Example

let months: Array<string> = ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]; //array with all string values.

let years: Array<number> = [2015, 2016, 2017, 2018, 2019]; //array will all numbers

let month_year: Array<string | number> = ["Jan", 2015, "Feb", 2016]; //array with string and numbers mixed.

let alltypes: Array<any> = [true, false, "Harry", 2000, { "a": "50", "b": "20" }]; //array of all types boolean, string , number , object etc.

Different Ways to access elements from an Array

To get the elements from an array, the values starts from index 0 to the length of the array.

Example:

let years: Array<number> = [ 2016, 2017, 2018, 2019]; //array will all numbers			
years[0]; // output will be 2016			
years[1]; // output will be 2017			
years[2]; // output will be 2018			
years[3]; // output will be 2019

You can also get the elements from an array using TypeScript for loop as shown below:

Using TypeScript for loop

let years: Array<number> = [ 2016, 2017, 2018, 2019]; 
for (let i=0;i<=years.length; i++) {
     console.log(years[i]);
}
Output:
2016
2017
2018
2019

Using for-in loop

let years: Array<number> = [ 2016, 2017, 2018, 2019]; 
for (let i in years) {
     console.log(years[i])
}

Output:
2016
2017
2018
2019

Using for-of loop

let years: Array<number> = [ 2016, 2017, 2018, 2019]; 
for (let  i of years) {
     console.log(i)
}
Output:
2016
2017
2018
2019

Using foreach loop

let years: Array<number> = [ 2016, 2017, 2018, 2019]; 
years.forEach(function(yrs, i) {
  console.log(yrs);
});
Output:
2016
2017
2018
2019

TypeScript Array Methods

TypeScript Array object has many properties and methods which help developers to handle arrays easily and efficiently. You can get the value of a property by specifying arrayname.property and the output of a method by specifying array name.method().

length property

=> If you want to know the number of elements in an array, you can use the length property.

Reverse method

=> You can reverse the order of items in an array using a reverse method.

Sort method

=> You can sort the items in an array using sort method.

Pop method

=> You can remove the last item of an array using a pop method.

Shift method

=> You can remove the first item of an array using shift method.

Push method

=> You can add value as the last item of the array.

concat method

=> You can join two arrays into one array element.

Example for length property

let months: Array<string> = ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]; //array with all string values.

console.log(months.length);  // 12

Example for reverse method

let months: Array<string> = ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]; //array with all string values.

console.log(months.reverse());  //  ["Dec", "Nov", "Oct", "Sept", "Aug", "July", "June", "May", "April", "March", "Feb", "Jan"]

Example for sort method

let months: Array<string> = ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]; //array with all string values.

console.log(months.sort()); // ["April", "Aug", "Dec", "Feb", "Jan", "July", "June", "March", "May", "Nov", "Oct", "Sept"]

Example for pop method

let months: Array<string> = ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]; //array with all string values.				

console.log(months.pop()); //Dec

Example for shift method

let months: Array<string> = ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]; //array with all string values.			

console.log(months.shift()); // Jan

Example for push method

let years: Array<number> = [2015, 2016, 2017, 2018, 2019]; //array will all numbers			
console.log(years.push(2020)); 			
years.forEach(function(yrs, i) {			
  console.log(yrs); // 2015 , 2016,2017, 2018, 2019,2020				
});

Example for concat method

let array1: Array<number> = [10, 20, 30]; 			
let array2: Array<number> = [100, 200, 300];			
console.log(array1.concat(array2)); //[10, 20, 30, 100, 200, 300]

Class in TypeScript

TypeScript is a superset of JavaScript, so whatever possible to do in JavaScript is also possible in TypeScript. Class is a new feature added from ES6 onward, so earlier in JavaScript the class type functionality was tried using a function with prototype functionality to reuse code. Using class, you can have our code almost close to languages like java, c#, python, etc., where the code can be reused. With the feature of class in TypeScript/JavaScript, it makes the language very powerful.

Defining a Class in TypeScript

Here is a basic class syntax in TypeScript:

class nameofclass {
     //define your properties here

    constructor() {
     // initialize your properties here
    }
 
   //define methods for class
}

Example: A working example on Class

class Students {
    age : number;
    name : string;
    roll_no : number;
    
    constructor(age: number, name:string, roll_no: number) {
        this.age = age;
        this.name = name;
        this.roll_no = roll_no;
    }

    getRollNo(): number {
        return this.roll_no;
    }

    getName() : string {
        return this.name;
    }

    getAge() : number {
        return this.age;
    }
}

In the above example, you have a class called Students. It has properties age, name, and roll_no.

Constructor in a TypeScript Class

The class Students example we have defined above, it has a constructor as shown below :

constructor(age: number, name:string, roll_no: number) {
        this.age = age;
        this.name = name;
        this.roll_no = roll_no;
    }

The constructor method has params age, name, and roll_no. The constructor will take care of initializing the properties when the class is called. The properties are accessed using this keyword. Example this.age to access age property, this.roll_no to access roll_no, etc. You can also have a default constructor, as shown below:

constructor () {}

Methods inside a TypeScript Class

The class Students example there are methods defined for example getRollNo(), getName(), getAge() which are used to give details of properties roll_no, name and age.

getRollNo(): number {
        return this.roll_no;
}

getName() : string {
	return this.name;
}

getAge() : number {
	return this.age;
}

Creating Instance of Class in TypeScript

Example:

In TypeScript to create an instance of a class you need to use the new operator. When we create an instance of a class using new operator we get the object which can access the properties and methods of the class as shown below:

let student_details = new Students(15, "Harry John", 33);
student_details.getAge(); // 15
student_details.getName(); // Harry John

Compiling TypeScript Class to JavaScript

You can use tsc command as shown below to compile to Javascript.

Command: tsc  Students.ts

The output of Javascript code on compilation is as shown below:

var Students = /** @class */ (function () {
    function Students(age, name, roll_no) {
        this.age = age;
        this.name = name;
        this.roll_no = roll_no;
    }
    Students.prototype.getRollNo = function () {
        return this.roll_no;
    };
    Students.prototype.getName = function () {
        return this.name;
    };
    Students.prototype.getAge = function () {
        return this.age;
    };
    return Students;
}());

In Javascript, the Class is converted into a self invoked function.

Class Inheritance

Classes can be inherited using the extend keyword in TypeScript.

Class Inheritance Syntax:

class A {
     //define your properties here

    constructor() {
     // initialize your properties here
    }
 
   //define methods for class

}

class B extends A {
 //define your properties here

    constructor() {
     // initialize your properties here
    }
 
   //define methods for class

}

class B will be able to share class A methods and properties.

Here is a working example of a class using Inheritance

class Person {
    name: string;
    age: number;

    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    getName(): string {
        return this.name;
    }

    getAge(): number {
        return this.age;
    }
}

class Student extends Person {
    tmarks: number;
    getMarks(): number {
        return this.tmarks;
    }

    setMarks(tmarks) {
        this.tmarks = tmarks;
    }
}

let _std1 = new Student('Sheena', 24);
_std1.getAge(); // output is 24
_std1.setMarks(500);
_std1.getMarks(); // output is 500

You have two classes, Person and Student. Student class extends Person, and the object created on Student is able to access its own methods and properties as well as the class it has extended.

Now let us add some more changes to the above class.

Example:

class Person {
    name: string;
    age: number;

    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    getName(): string {
        return this.name;
    }

    getAge(): number {
        return this.age;
    }
}

class Student extends Person {
    tmarks: number;
    constructor(name: string, age: number, tmarks: number) {
        super(name, age);
    }
    getMarks(): number {
        return this.tmarks;
    }

    setMarks(tmarks) {
        this.tmarks = tmarks;
    }
}

let _std1 = new Student('Sheena', 24, 500);
_std1.getAge(); // output is 24
_std1.getMarks(); // output is 500

The changes that you have added in comparison to the previous example is there is a constructor defined in class Student. The constructor has to take the same params as the base class and add any additional params of its own if any.

In TypeScript you need to call super will all the params as the bases params in it. This has to be the first thing to be done inside the constructor. The super will execute the constructor of the extended class.

Access Modifiers in TypeScript

TypeScript supports public, private, and protected access modifiers to your methods and properties. By default, if access modifiers are not given the method or property is considered as public, and they will be easily accessible from the object of the class.

In case of private access modifiers, they are not available to be accessed from the object of the class and meant to be used inside the class only. They are not available for the inherited class.

In case of protected access modifiers, they are meant to be used inside the class and the inherited class and will not be accessible from the object of the class.

Example:

class Person {
    protected name: string;
    protected age: number;

    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    private getName(): string {
        return this.name;
    }

    getDetails(): string {
        return "Name is "+ this.getName();
    }
}

class Student extends Person {
    tmarks: number;
    constructor(name: string, age: number, tmarks: number) {
        super(name, age);  
        this.tmarks = tmarks;    
    }
    getMarks(): number {
        return this.tmarks;
    }

    getFullName(): string {
        return this.name;
    }
    
    setMarks(tmarks) {
        this.tmarks = tmarks;
    }
}

let _std1 = new Student('Sheena', 24, 500);
_std1.getMarks(); // output is 500
_std1.getFullName(); // output is Sheena
_std1.getDetails(); // output is Name is Sheena
  • Private: properties or methods cannot be accessed by the object of the class and also the derived class, they are meant to be used internally inside the class.
  • Protected: properties and methods also cannot be accessed by the object created. They are accessible from inside the class and available to the class extending it.
  • Public: properties and methods are declared without any keyword. They are easily accessed using the object of the class from outside.

Interface in TypeScript

One of the core features of TypeScript is interfaces. The interface is a set of a rule defined which needs to be implemented by the entity using it. The entity can be a class, function, or variable. An interface can be made up of properties and methods. You can define properties as optional using “?” syntax for that property or method. The interface adds a strong type check for any function, variable, or class implementing the interface.

Syntax of an Interface in TypeScript

interface Dimension {
    width: string;
    height: string;
}

You have defined an interface named as Dimension which has properties width and height, and both have type as a string.

Now this interface can be implemented by a variable, a function, or a class. Here is the example of variable implementing the interface Dimension.

Example:

interface Dimension {
    width: string;
    height: string;
}

let _imagedim: Dimension = {
    width: "100px",
    height: "200px"
};

The signature of the interface Dimension has width and height, and both are mandatory. In case while implementing the interface, any of the property is missed, or the type is changed, it will give a compile time error while compiling the code to javascript.

The above code, when compiled to javascript, looks as follows:

var _imagedim = {
    width: "100px",
    height: "200px"
};

Let us now see how to use an interface with a function.

Using Interface on a function as a return type

Example:

interface Dimension {
    width: string;
    height: string;
}

function getDimension() : Dimension {
    let width = "300px";
    let height = "250px";
    return {
        width: width,
        height: height
    }
}

In the above example, the interface Dimension is implemented on the function getDimension() as the return type. The return type of getDimension() has to match with the properties and type mentioned for Interface Dimension.

The compiled code to Javascript will be as follows:

function getDimension() {
    var width = "300px";
    var height = "250px";
    return {
        width: width,
        height: height
    };
}

During compilation, if the return type does not match with the interface, it will throw an error.

Interface as function parameter

interface Dimension {
    width: string;
    height: string;
}

function getDimension(dim: Dimension) : string {
    let finaldim  = dim.width +"-"+ dim.height;
    return finaldim;
}

getDimension({width:"300px", height:"250px"}); // will get "300px-250px"

So above example, you have used Interface Dimension as a parameter to the function getDimension(). When you call the function, you need to make sure the parameter passed to it matches to the Interface rule defined.

The compiled code to Javascript will be as follows:

function getDimension(dim) {
    var finaldim = dim.width + "-" + dim.height;
    return finaldim;
}
getDimension({ width: "300px", height: "250px" });

Class implementing Interface

To make use of interface with a class, you need to use the keyword implements.

Syntax for Class implementing an interface:

class NameofClass implements InterfaceName {
}

Following example shows working of interface with class.

interface Dimension {
    width : string,
    height: string,
    getWidth(): string; 
}

class Shapes implements Dimension {
    width: string;
    height: string;
    constructor (width:string, height:string) {
        this.width = width;
        this.height = height;
    }
    getWidth() {
        return this.width;
    }
}

In the above example, you have defined interface Dimension with properties width and height both of type string and a method called getWidth() which has return value as a string.

The compiled code to Javascript will be as follows:

var Shapes = /** @class */ (function () {
    function Shapes(width, height) {
        this.width = width;
        this.height = height;
    }
    Shapes.prototype.getWidth = function () {
        return this.width;
    };
    return Shapes;
}());

Functions in TypeScript

Functions are set of instructions performed to carry out a task. In Javascript, most of the code is written in the form of functions and plays a major role. In TypeScript, you have class, interfaces, modules, namespaces available, but still, functions play an important role. The difference between the function in javascript and TypeScript function is the return type available with TypeScript function.

JavaScript function:

function add (a1, b1) { 
   return a1+b1;
}

TypeScript function:

function  add(a1 : number, b1: number) : number {
    return a1 + b1;
}

In the above functions, the name of the function is added, the params are a1, and b1 both have a type as a number, and the return type is also a number. If you happen to pass a string to the function, it will throw a compile-time error while compiling it to JavaScript.

Making call to the function: add

let  x = add(5, 10) ;  // will return 15
let  b = add(5); // will throw an error : error TS2554: Expected 2 arguments, but got 1.
let c = add(3,4,5); // will throw an error : error TS2554: Expected 2 arguments, but got 3.
let t = add("Harry", "John");// will throw an error :  error TS2345: Argument of type '"Harry"' is not assignable to parameter of type 'number'.

The params a1 and b1 are mandatory parameters and will throw an error if not received in that manner. Also, the param type and return type is very important and cannot change once defined.

Optional parameters to a function

In javascript, all the parameters to the functions are optional and considered as undefined if not passed. But same is not the case with TypeScript, once you define the params you need to send them too, but in case you want to keep any param optional, you can do so by using? against the param name as shown below:

function getName(firstname: string, lastname?: string): string {
    return firstname + lastname;
}

let a = getName("John"); // will return Johnundefined.
let b = getName("John", "Harry"); // will return JohnHarry
let c = getName("John", "H", "Harry"); // error TS2554: Expected 1-2 arguments, but got 3.

Please note that the optional params are to be defined in a function at the last only, you cannot have the first param as optional and second param as mandatory.When you call the function with one param compiler will throw an error. So it is necessary to keep the optional params at the end.

Assign Default Values to Params

You can assign default values to params as shown below:

function getName(firstname: string, lastname = "Harry"): string {
    return firstname + lastname;
}

let a = getName("John"); // will return JohnHarry
let b = getName("John", "H"); // will return JohnH

Similar to optional params, here too default initialized params has to be kept at the end in a function.

Rest Parameters

You have seen how TypeScript handles mandatory params, optional params, and the default value initialized params. Now, will take a look at rest params. Rest params are a group of optional params defined together, and they are defined using three dots (…) followed by the name of the param, which is an array.

Syntax for Rest params:

function testFunc(a: string, ...arr: string[]) :string {
    return a + arr.join("");
}

As shown above, the rest params are defined using (…param-name); the rest param is an array prefixed by three dots. The array will have all the params passed to it. You can call the function, as shown in the example below:

Example:

let a = testFunc("Monday", "Tuesday", "Wednesday", "Thursday"); // will get output as MondayTuesdayWednesdayThursday

Arrow Functions

An arrow function is one of the important features released in ES6, and it is available in TypeScript too. Arrow function syntax has a fat arrow in it due to which the function is called an arrow function.

Arrow function Syntax:

var nameoffunction = (params) => {				
 // code here			
}

What is the use of Arrow Function?

Let’s take a look at the example to understand the use case of Arrow function:

Example:

var ScoreCard = function () {
    this.score = 0;

    this.getScore = function () {
        setTimeout(function () {
            console.log(this.score);    // gives undefined.    
        }, 1000);
    }    
}

var a = new ScoreCard();
a.getScore();

You have created an anonymous function which has a property this. Score initialize to 0 and a method getScore which internally has a setTimeout, and in 1 second it consoles this.score. The consoled value gives undefined though you have this.score defined and initialized. The issue here is with this keyword. The function inside setTimeout has its own this, and it tries to refer the score internally, and since it is not defined, it gives undefined.

The same can be taken care using Arrow function as shown below:

var ScoreCard = function () {
    this.score = 0;

    this.getScore = function () {
        setTimeout(()=>{
            console.log(this.score);   // you get  0
        }, 1000);
    }    
}

var a = new ScoreCard();
a.getScore();

You have changed the function inside setTimeout to a arrow function as shown below:

setTimeout(()=>{
            console.log(this.score);   // you get  0
        }, 1000);

An arrow function does not have its own this defined and it shares its parent this, so variables declared outside are easily accessible using this inside an arrow function. They are useful because of the shorter syntax as well as for callbacks, event handlers, inside timing functions, etc.

TypeScript Enums

TypeScript Enum is an object which has a collection of related values stored together. Javascript does not support enums. Most of the programming language like Java, C, C++ supports TypeScript Enum and it also available with TypeScript too. Enums are defined using keyword enum.

How to declare an Enum?

Syntax:

enum NameofEnum {
   value1,
   value2,
    ..
}

Example: Enum

enum Directions {
North,
South,
East,
West
}

In the above example, you have defined an enum called Directions. The value given is North, South, East, West. The values are numbered from 0 for the first value in the enum and subsequently increments by 1 for the next value.

Declare An Enum with a numeric value

By default, if an enum is not given any value, it considers it a number starting from 0. Following example shows an enum with a numeric value.

enum Directions {
North = 0,
South = 1, 
East =2,
West =3
}

You may also assign a start value to the enum and the next enum values will get the incremented values. For example:

enum Directions {
North = 5,
South, // will be 6
East, // 7
West // 8
}

Now the enum value North starts with 5, so South will get value as 6, East = 7 and West = 8.

You may also assign values of your choice instead of taking the default ones. For Example:

enum Directions {
North = 5,
South = 4,
East = 6,
West = 8
}

How to access an Enum?

Following example shows how to make use of Enum in your code:

enum Directions {
    North,
    South,
    East,
    West
}

console.log(Directions.North); // output is  0
console.log(Directions["North"]); // output is 0
console.log(Directions[0]); //output is North

The compiled code to javascript is as follows:

var Directions;
(function (Directions) {
    Directions[Directions["North"] = 0] = "North";
    Directions[Directions["South"] = 1] = "South";
    Directions[Directions["East"] = 2] = "East";
    Directions[Directions["West"] = 3] = "West";
})(Directions || (Directions = {}));
console.log(Directions.North);
console.log(Directions["North"]);
console.log(Directions[0]);

Since Javascript does not support enums, it converts the enum into a self invoked functions as shown above.

Declare An Enum with a string value

You can assign string values of your choice, as shown in the example below:

Example:

enum Directions {
    North = "N",
    South = "S",
    East = "E",
    West = "W"
}

console.log(Directions.North); // output is N
console.log(Directions["North"]); // output is N
console.log(Directions[0]); // output is North

The compiled code to javascript is as follows:

var Directions;
(function (Directions) {
    Directions["North"] = "N";
    Directions["South"] = "S";
    Directions["East"] = "E";
    Directions["West"] = "W";
})(Directions || (Directions = {}));
console.log(Directions.North);
console.log(Directions["North"]);
console.log(Directions[0]);

What are the Modules in TypeScript?

The files created in TypeScript have global access, which means that variables declared in one file are easily accessed in another file. This global nature can cause code conflicts and can cause issues with execution at run-time. You have export and import module functionality which can be used to avoid global variable, function conflicts. This feature is available in JavaScript with ES6 release and also supported in TypeScript.

Why do you need Modules in TypeScript?

Following example shows the issue without modules:

Example test1.ts

let age : number = 25;

You have defined a variable age of type number in test1.ts.

Example test2.ts

In test2.ts file you are easily able to access the variable age defined in test1.ts and also modify it as shown below:

age = 30; // changed from 25 to 30.
let _new_age = age;

So the above case can create a lot of problems as the variables are globally available and can be modified.

With Modules, the code written remains locale to the file and cannot be accessed outside it. To access anything from the file, it has to be exported using the export keyword. It is used when you want the variable, class, function, or interface to be used in another file. Import is used when you want to access the exported variable, class, or interface or function too. Doing so the code is written remains intact within the file, and even if you define same variable names, they are not mixed up and behave local to the file where they are declared.

Using Export and Import

There are many ways to export and import. So will discuss syntax here which is mostly used.

The syntax for import and export 1:

export  nameofthevariable or class name or interface name etc

//To import above variable or class name or interface you have to use import as shown below:
 

Import {nameof thevariable or class name or interfacename} from "file path here without.ts"

Here is a working example using export and import.

Example:

test1.ts

export let age: number = 25;

Export keyword is used to share age variable in another file.

test2.ts

import { age } from "./test1"
let new_age :number = age;

Import keyword is used to access the age variable, and you need to specify the file location as shown above.

Syntax for import and export 2:

There is another way to export, and import and the syntax for the same is as shown below:

export = classname;

import classname = require(“file path of modulename”)

When you are using export = to export your module, the import has to use require(“file path of modulename”) to import it.

Here is a working example showing the above case:

Customer.ts

class Customer {
    name: string;
    age: number;

    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    getName(): string {
        return this.name;
    }
}

export = Customer;

testCustomer.ts

import Customer = require("./Customer");

let a = new Customer("Harry", 30);
alert(a.getName());

Module Loader

Modules cannot work on its own, so you need module loader to locate the import dependencies as you have seen in TypeScript examples shown above. The module loader available is CommonJS for nodejs and Require.js to run in the browser.

To compile code using CommonJS module use following command:

tsc --module commonjs testCustomer.ts

To compile code using Requirejs module use following command:

tsc --module amd testCustomer.ts

The dependent files will get converted to js file with above command.

Example testCustomer.ts to testCustomer.js using Requirejs

define(["require", "exports", "./Customer"], function (require, exports, Customer) {
    "use strict";
    exports.__esModule = true;
    var a = new Customer("Harry", 30);
    alert(a.getName());
});

Example Customer.ts to Customer.js using Requirejs

define(["require", "exports"], function (require, exports) {
    "use strict";
    var Customer = /** @class */ (function () {
        function Customer(name, age) {
            this.name = name;
            this.age = age;
        }
        Customer.prototype.getName = function () {
            return this.name;
        };
        return Customer;
    }());
    return Customer;
});

To test it using require.js, you need to create a file called main.js, which has reference to the dependencies as shown.

Here is the folder structure:

src/
    Customer.js
    testCustomer.js
    main.js
    require.js  // you can get this file from github or npm install requirejs
    test.html

main.js

define(function (require) {
    var customer = require("./Customer");
    var testCustomer = require("./testCustomer");
});

test.html

<!DOCTYPE html>			
<html>			
<head>			
    <title>TypeScript Module testing using Requirejs</title>			
    <script data-main="main" src="require.js"></script>			
</head>			
<body>			
    <h3>Testing modules using Requirejs</h3>			
</body>			
</html>

Module Loader

Namespaces in TypeScript

Namespace is basically has collection of classes, interfaces, variables, functions together in one file.

Namespace Syntax

namespace name{

export class {
}

export interface {
}

export const constname;

}

The code related in available under one namespace.

Namespace working example: testnamespace.ts

namespace StudentSetup {

    export interface StudDetails {
        name: string;
        age: number;
    }

    export function addSpace(str) { // will add space to the string given
        return str.split("").join(" ");
    }

    export class Student implements StudDetails {
        name: string;
        age: number;

        constructor(studentdetails: StudDetails) {
            this.name = studentdetails.name;
            this.age = studentdetails.age;
        }

        getName(): string {
            return this.name;
        }
    }
}

The name of the namespace is StudentSetup, you have added a interface StudDetails , function addSpace and a class called Student.

Accessing Namespace

Following is the code where you are using the namespace StudentSetup.

testStudentSetup.ts

let a = new StudentSetup.Student({ name: "Harry", age: 20 });

console.log("The name is :" + StudentSetup.addSpace(a.getName()));

The class, interface, a function available inside a namespace has to be referred using the name of the namespace example StudentSetup.addSpace to access the function, StudentSetup.Student to access the class.

You can compile both files into one js as shown below:

tsc --outFile namespace.js testnamespace.ts  testStudentSetup.ts

Check the output in command prompt using below command:

node namespace.js

It will display output as :

The name is: H a r r y

Ambient Declarations in TypeScript

TypeScript allows you to use third-party javascript files using ambient declaration. The advantage of this feature is that you don’t have to rewrite and yet use all the features of the library in TypeScript.

Ambient Syntax

To declare ambient module:

declare module moduleName {
   //code here
}

The ambient file has to saved as :

filename.d.ts

To use the file filename.d.ts in your .ts you need to refer it as:

/// <reference path="filename.d.ts"/>

The ambient type declaration in TypeScript will have a reference to the third party library and will re-declare the functions required with its own type. For example, consider you have a small javascript library, as shown below:

Third Party JavaScript file: testString.js

Example: testString.js

var StringChecks = {
    isString: function (str) {
        return typeof str === "string";
    },

    convertToUpperCase: function (str) {
        return str.toUpperCase();
    },

    convertToLowerCase: function (str) {
        return str.toLowerCase();
    },

    convertToStringBold: function (str) {
        return str.bold();
    }
};

You have an object called StringChecks which has functions like isString, convertToUpperCase, convertToLowerCase, and converToStringBold.

Creating of Ambient Module in TypeScript

Now will create an ambient module which will have reference to above js functions and also add type check as per our requirements.

Filename : tstring.d.ts

declare module TestString {

    export interface StringsFunc {
        isString(str: string): boolean;
        convertToUpperCase(str: string): string;
        convertToLowerCase(str: string): string;
        convertToStringBold(str: string): string;
    }
}

declare var StringChecks: TestString.StringsFunc;

You have to define a module name as TestString and have exported interface StringsFunc.

isString(str: string): boolean

=> This will take param as a string and the return type will be boolean. When using in your .ts file in case you happen to pass the param as a number or anything other than string it will give you a compile type error.

convertToUpperCase(str:string): string

=> This will take argument as string and return a string.Same goes for convertToLowerCase(str: string)
: string; and convertToStringBold(str: string): string
;

Since in the javascript file you have the object name as StringChecks, finally we need to refer the same in the .d.ts file which is done as :

declare var StringChecks: TestString.StringsFunc;

Using Ambient module in TypeScript

Now here is the test.ts file where will use ambient file tstring.d.ts

Example: test.ts

/// <reference path="tstring.d.ts"/>
let str1 = StringChecks.isString("Hello World");
console.log(str1);
let str2 = StringChecks.convertToUpperCase("hello world");
console.log(str2);
let str3 = StringChecks.convertToLowerCase("HELLO");
console.log(str3);
let str4 = StringChecks.convertToStringBold("Hello World");
console.log(str4);

Compile TypeScript tsc test.ts to test.js

/// <reference path="tstring.d.ts"/>
var str1 = StringChecks.isString("Hello World");
console.log(str1);
var str2 = StringChecks.convertToUpperCase("hello world");
console.log(str2);
var str3 = StringChecks.convertToLowerCase("HELLO");
console.log(str3);
var str4 = StringChecks.convertToStringBold("Hello World");
console.log(str4);

Now you can use test.js in html file and also the library file testString.js

<html>			
<head>			
    <title>Test TypeScript Ambient</title>			
    <script src="testStrings.js"></script>			
    <script src="test.js"></script>			
</head>			
<body>			
</body>			
</html>

This is the output seen in the console:

true			
HELLO WORLD			
hello			
<b>Hello World</b>

TypeScript History

Let see important landmarks from the history of TypeScript:

  • After two years of internal development at Microsoft. TypeScript 0.9, released in 2013
  • Additional support for generics TypeScript 1.0 was released at Build 2014
  • In July 2014, a new TypeScript compiler came which is five times faster than it’s the previous version.
  • In July 2015, support for ES6 modules, namespace keyword, for, of support, decorators.
  • In November 2016, an added feature like key and lookup types of mapped types, and rest.
  • On March 27, 2018, conditional types, the improved key with intersection types supports added in the TypeScript.

Why use TypeScript?

Here, are important pros/benefits of using TypeScript

  • Big and complex project in JavaScript are difficult to code and maintain.
  • TypeScript helps a lot in code organization and yet gets rid of most of the errors during compilation.
  • TypeScript supports JS libraries & API Documentation
  • It is optionally typed scripting language
  • TypeScript Code can be converted into plain JavaScript Code
  • Better code structuring and object-oriented programming techniques
  • Allows better development time tool support
  • It can extend the language beyond the standard decorators, async/await

Who uses TypeScript?

Here, are some most common applications of TypeScript:

  • The angular team uses TypeScript.
  • NodeJS and NPM Installation
  • TypeScript Installation
  • Compile TypeScript code to Javascript
  • Execute Code using Nodejs
  • Execute Javascript in Browser
  • Compile TypeScript code to Javascript using EcmaScript version
  • You can easily compile code written in TypeScript to JavaScript using NodeJS.
  • So to work with TypeScript you need first to download and install NodeJS.

Summary

  • TypeScript is a superset of JavaScript. TypeScript is pure object-oriented programming language that supports classes, interfaces, etc.
  • TypeScript supports all the Ecmascript features released, and developers can use the same while coding.
  • Variables are used to store values, and the value can be a string, number, Boolean, or an expression.
  • In TypeScript, the type to a variable is defined at the start only and through the execution, it has to maintain the same type any changes to it will lead to a compile-time error during compilation to javascript.
  • An Array in TypeScript is a data type wherein you can store multiple values.
  • Class is a new feature added from ES6 onward, so earlier in JavaScript the class type functionality was tried using a function with prototype functionality to reuse code.
  • TypeScript supports public, private, and protected access modifiers to your methods and properties.
  • One of the core features of TypeScript is interfaces. The interface is a set of a rule defined which needs to be implemented by the entity using it.
  • Functions are set of instructions performed to carry out a task.
  • TypeScript Enum is an object which has a collection of related values stored together.