Typescript Tutorial

Introduction

TypeScript is a free and open-source programming language created and maintained by Microsoft. It is a superset of JavaScript, which means that it builds upon the existing syntax and features of JavaScript and adds new features on top of it. TypeScript is gaining popularity among software developers and has been adopted by several organizations worldwide.

This article aims to provide an in-depth tutorial on TypeScript, covering basic and advanced concepts, including data types, operators, functions, classes, modules, and more.

History of TypeScript

TypeScript was first introduced by Microsoft in 2012 and was created by the same team that developed the C# programming language. The creators of TypeScript wanted to add more structure and type safety to JavaScript and make it easier for developers to build large-scale applications.

TypeScript is considered a superset of JavaScript, which means it builds upon the existing syntax and features of JavaScript while adding new features on top of it. Some of the key features of TypeScript include static typing, classes, interfaces, modules, and other features that make it easier to build and maintain large-scale applications.

Benefits of using TypeScript

The primary goal of TypeScript is to provide better tooling and type safety for JavaScript. Static types are used to detect syntax errors and common programming mistakes and prevent them from propagating through the codebase, making it easier to debug and maintain the code.

TypeScript offers several benefits over traditional JavaScript, including:

  1. Better tooling support: TypeScript comes with a command-line interface that provides better support for debugging, linting, and building applications.
  2. Improved code quality: Static types help detect and prevent coding errors, leading to more efficient and error-free code.
  3. Enhanced productivity: TypeScript supports class-based object-oriented programming, making it easier to organize and manage code. It also supports modular programming, which allows developers to split their code into smaller modules.
  4. Compatibility with existing JavaScript code: TypeScript is fully compatible with existing JavaScript code, meaning that developers can easily migrate their existing codebase to TypeScript without any changes.

Setup

Before we dive into TypeScript, we need to set up our development environment. Here are the steps to follow:

  1. Install Node.js: TypeScript is built on top of Node.js, so you’ll need to have Node.js installed on your system. You can download it from the official website.
  2. Install TypeScript: To install TypeScript, you will need to open your Terminal or Command Prompt and run the following command:
npm install -g typescript

Once installed, you can check the version of TypeScript by running the following command:

tsc --version
  1. Create a new TypeScript file: Create a new file called ‘app.ts’ and save it in a directory of your choice.
  2. Edit the file: Open the ‘app.ts’ file and add the following code:
let message : string = "Hello, TypeScript!";
console.log(message);
  1. Compile the file: To compile the ‘app.ts’ file, you need to open your Terminal or Command Prompt and navigate to the directory where the file is located. Then, run the following command:
tsc app.ts 

This will create a new file called ‘app.js’ which contains the compiled JavaScript code.

  1. Run the file: To run the ‘app.js’ file, you can use Node.js by running the following command:
node app.js

This will output the message “Hello, TypeScript!” to the console.

Basic Types

In TypeScript, there are several data types that we can use to declare variables. These include:

  1. Number: Represents numeric values, including integers and floating-point numbers.
  2. String: Represents a sequence of characters.
  3. Boolean: Represents a logical value, either true or false.
  4. Array: Represents a collection of elements of the same type.
  5. Tuple: Represents an array of fixed size where each element can be of a different type.
  6. Enum: Represents a set of named constants.

Let’s take a closer look at each of these data types.

Numbers

To declare a numeric value in TypeScript, we can use the number type. For example:

let x: number = 10;
let y: number = 3.14;

In the above code, we declare two variables, ‘x’ and ‘y’, with the number type. We can also perform mathematical operations on these variables, such as addition, subtraction, multiplication, and division.

let z: number = x + y; // 13.14
let a: number = x - y; // 6.86
let b: number = x * y; // 31.4
let c: number = x / y; // 3.1847133757961785

Strings

To declare a string value in TypeScript, we can use the string type. For example:

let message: string = "Hello, TypeScript!";

In the above code, we declare a variable called ‘message’ with the string type and assign it the value “Hello, TypeScript!”. We can also perform operations on strings, such as concatenating two or more strings.

Boolean

To declare a boolean value in TypeScript, we can use the boolean type. For example:

let isTrue: boolean = true;
let isFalse: boolean = false;

Arrays

To declare an array in TypeScript, we can use the array type. For example:

let numbers: number[] = [1, 2, 3, 4, 5];
let names: string[] = ["John", "Mary", "David"];

In the above code, we declare two arrays, ‘numbers’ and ‘names’, by using the square brackets notation. We can access individual elements of an array by using its index, starting from 0.

let secondNumber: number = numbers[1]; // 2
let firstName: string = names[0]; // John

Tuples

A tuple represents an array of fixed size where each element can be of a different type. To declare a tuple in TypeScript, we can use the tuple type. For example:

let person: [string, number, boolean] = ["John", 30, true];

In the above code, we declare a tuple called ‘person’ that contains three elements of different types: a string (name), a number (age), and a boolean (isMarried). We can access individual elements of a tuple using its index, starting from 0.

let name: string = person[0]; // John
let age: number = person[1]; // 30
let isMarried: boolean = person[2]; // true

Enum

An enum represents a set of named constants. To declare an enum in TypeScript, we can use the enum keyword. For example:

enum Color {
    Red,
    Green,
    Blue
}

let myColor: Color = Color.Green;

In the above code, we declare an enum called ‘Color’ with three named constants: Red, Green, and Blue. We can assign a value to an enum constant explicitly, or if no value is assigned, TypeScript will automatically assign a value starting from 0.

In this example, we assign the value ‘Green’ to a variable called ‘myColor’. We can also access individual constants of an enum by using dot notation.

console.log(Color.Red); // 0
console.log(Color.Green); // 1
console.log(Color.Blue); // 2

Operators and Functions

In TypeScript, we have several operators that we can use to perform arithmetic, relational, and logical operations. We also have functions, which are blocks of code that perform a specific task and can be reused throughout the codebase.

Arithmetic Operators

The arithmetic operators in TypeScript are the same as in JavaScript, and they include:

  • Addition (+)
  • Subtraction (-)
  • Multiplication (*)
  • Division (/)
  • Modulus (%)

Relational Operators

The relational operators in TypeScript are also the same as in JavaScript, and they include:

  • Greater than (>)
  • Less than (<)
  • Greater than or equal to (>=)
  • Less than or equal to (<=)
  • Equality (==)
  • Inequality (!=)

Logical Operators

The logical operators in TypeScript are also the same as in JavaScript, and they include:

  • And (&&)
  • Or (||)
  • Not (!)

If-else statements

The if-else statements in TypeScript are used to conditionally execute code based on a boolean expression. For example:

let age: number = 30;

if (age >= 18) {
    console.log("You are an adult!");
} else {
    console.log("You are not an adult yet.");
}

In the above code, we check if the variable ‘age’ is greater than or equal to 18. If it is, we output the message “You are an adult!”, otherwise, we output the message “You are not an adult yet.”.

Switch statement

The switch statement in TypeScript is used to perform different actions based on different conditions. For example:

let day: string = "Monday";

switch (day) {
    case "Monday":
        console.log("It's Monday, time to go back to work.");
        break;
    case "Tuesday":
        console.log("It's Tuesday, still a long way to the weekend.");
        break;
    case "Wednesday":
        console.log("It's Wednesday, halfway there!");
        break;
    default:
        console.log("It's a weekday, keep working!");
}

In the above code, we check which day it is and output an appropriate message based on the day. If it’s Monday, we output “It’s Monday, time to go back to work.”, if it’s Tuesday, we output “It’s Tuesday, still a long way to the weekend.”, and so on.

For and While loops

The for and while loops in TypeScript are used to repeat a block of code multiple times. For example:

In the above code, we use a for loop to iterate over numbers from 1 to 10 and output them to the console.

let i = 1;
while (i <= 10) {
    console.log(i);
    i++;
}

In the above code, we use a while loop to do the same thing by initializing a variable called ‘i’ to 1, and we keep looping until the value of ‘i’ is greater than 10.

Functions

In TypeScript, we can declare functions using the function keyword. Functions can have parameters, which are inputs that we can pass to them, and they can also have a return type, which is the type of the output that the function will produce.

For example, let’s declare a function that takes two numbers as inputs and returns their sum.

function sum(a: number, b: number): number {
    return a + b;
}

let result: number = sum(10, 20);
console.log(result); // 30

In the above code, we declare a function called ‘sum’ that takes two numbers as inputs and returns their sum. We can call this function by passing two numbers as arguments, and it will output their sum to the console.

Optional and Default Parameters

In TypeScript, we can make function parameters optional by using the question mark (?) notation. We can also specify default values for parameters by using the equals (=) notation.

For example, let’s declare a function that takes two parameters, one of which is optional and the other has a default value.

function greet(name: string, msg?: string, age: number = 18): void {
    console.log(`Hello, ${name}! ${msg || ""} You are ${age} years old.`);
}

greet("John"); // Hello, John!  You are 18 years old.
greet("Mary", "How are you?"); // Hello, Mary! How are you? You are 18 years old.
greet("David", "", 25); // Hello, David! You are 25 years old.

In the above code, we declare a function called ‘greet’ that takes three parameters: ‘name’, ‘msg’, and ‘age’. The ‘msg’ parameter is optional and has a question mark notation, and the ‘age’ parameter has a default value of 18.

Rest Parameters

In TypeScript, we can use the rest parameter syntax to represent an indefinite number of arguments as an array. For example:

function sumAll(...nums: number[]): number {
    return nums.reduce((accumulator, currentValue) => accumulator + currentValue);
}

let result: number = sumAll(1, 2, 3, 4, 5);
console.log(result); // 15

In the above code, we declare a function called ‘sumAll’ that uses the rest parameter syntax to accept an indefinite number of arguments. We can pass any number of arguments, and the function will add them up and output their sum to the console.

Advanced Types

In TypeScript, we have several advanced types that allow us to build more complex data structures and create more modular code. These include:

  1. Interfaces
  2. Classes
  3. Generics
  4. Type Assertion

Interfaces

An interface is a way to define a custom type that describes the shape of an object. By defining an interface, we can enforce specific rules on the properties and methods of an object.

For example, let’s define an interface called ‘Person’ that has two properties: ‘name’ and ‘age’.

interface Person {
    name: string;
    age: number;
}

let john: Person = { name: "John", age: 30 };
let mary: Person = { name: "Mary", age: 25 };

In the above code, we define an interface called ‘Person’ that has two properties: ‘name’ and ‘age’. We can then create two objects based on this interface called ‘john’ and ‘mary’. We can access individual properties of an object using dot notation.

console.log(john.name); // John
console.log(mary.age); // 25

Classes

A class is a way to define a blueprint for creating objects. Classes encapsulate data and behavior in one place and provide a way to organize and reuse code.

For example, let’s define a class called ‘Person’ that has two properties: ‘name’ and ‘age’, and two methods: ‘greet’ and ‘getAge’.

class Person {
    name: string;
    age: number;

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

    greet(): void {
        console.log(`Hello, my name is ${this.name}.`);
    }

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

let john: Person = new Person("John", 30);
let mary: Person = new Person("Mary", 25);

john.greet(); // Hello, my name is John.
console.log(mary.getAge()); // 25

In the above code, we define a class called ‘Person’

that has two properties (‘name’ and ‘age’) and two methods (‘greet’ and ‘getAge’). We use the constructor method to initialize these properties when we create a new instance of the class. We then create two instances of the class, ‘john’ and ‘mary’.

We can call the ‘greet’ and ‘getAge’ methods on these instances to output messages to the console.

Generics

Generics allow us to write code that is reusable across different types and allows us to create flexible data structures. In TypeScript, we can declare a generic type by using the angle brackets notation (<>) and passing in the name of the generic type.

For example, let’s create a simple generic function that takes an array of any type and returns the first item in the array.

function getFirstItem<T>(arr: T[]): T {
    return arr[0];
}

let numbers: number[] = [1, 2, 3, 4, 5];
let names: string[] = ["John", "Mary", "David"];

let firstNumber: number = getFirstItem(numbers);
let firstName: string = getFirstItem(names);

console.log(firstNumber); // 1
console.log(firstName); // John

In the above code, we declare a function called ‘getFirstItem’ that takes an array of any type and returns the first item in the array. We use the angle brackets notation (<>) to declare a generic type parameter called ‘T’.

We then create two arrays called ‘numbers’ and ‘names’ of type number[] and string[], respectively. We call the ‘getFirstItem’ function passing in these arrays and assign the results to the variables ‘firstNumber’ and ‘firstName’.

Type Assertion

Type assertion allows us to manually set the type of a variable in TypeScript. We can use the as keyword or the angle brackets notation to accomplish this.

For example, let’s declare a variable called ‘myNumber’ and use type assertion to set its type to ‘number’.

let myNumber: any = "123";
let num: number = (<string>myNumber).length;
console.log(num); // 3

In the above code, we declare a variable called ‘myNumber’ of type ‘any’. We then use the angle brackets notation to assert its type to ‘string’, and we access its length property to output the value 3 to the console.

Conclusion

TypeScript is a powerful tool that extends the capabilities of JavaScript in many ways. It gives developers a way to write more modular, maintainable, and robust code. In this tutorial, we covered the basics of TypeScript, including data types, operators, functions, control flow statements, and advanced types. With this knowledge, you should have a solid understanding of TypeScript and its capabilities.

Learn Typescript Mixins: Avoid Spaghetti Code
Typescript

Learn Typescript Mixins: Avoid Spaghetti Code

As a software developer, I’ve been using Typescript for most of my latest projects. One of the most interesting features I’ve come across is Typescript Mixins. These allow for simple composability of classes and functions, which can help to reduce code complexity and improve maintainability. In this article, I’m going to provide a comprehensive guide […]

Typescript Utility Types
Typescript

Typescript Utility Types

Introduction Hi there, I’m excited to talk to you today about Typescript Utility Types. First, let’s provide a brief overview of what Typescript is for those who may not be familiar with it. Typescript is an open-source programming language that builds on top of JavaScript by adding static types to code. This can help catch […]

Typescript Declaration Merging
Typescript

Typescript Declaration Merging

Introduction Typescript Declaration Merging is an essential feature of the Typescript language, which allows developers to extend existing code without modifying it. It can be a bit complex and overwhelming for beginners, but once you understand how it works, you’ll find it to be a powerful tool. As a developer, you will come across scenarios […]