Nov 23, 2022 10 mins

Develop Angular applications using Typescript

Develop Angular applications using Typescript Develop Angular applications using Typescript

Creating web applications for modern browsers is easy with Typescript. It smoothly integrates with Javascript, providing a seamless development experience. In this beginner-friendly guide, we'll explore essential Typescript concepts to craft dynamic web applications.

Introduction to Typescript

Typescript was developed by Microsoft and the first stable version was released in 2012. It is a programmer-friendly language and you can achieve many advantages over Javascript. For example, Typescript supports user-defined data types, object-oriented programming, etc. Before diving into Typescript, I thought to clarify a few things that every beginner should know in the next section.

ES5 and ES6

What are ES5 and ES6? Both are different versions of the global scripting language standard introduced by the European Computer Manufacturers Association(ECMA). ES5 and ES6 were introduced in 2009 and 2015 respectively. ES6 has lots of enhanced features over ES5. Modern browsers don’t fully support ES6 stands yet. But they completely support the ES5 version. Typescript, primarily supporting ES6, relies on a transpiler to make applications compatible with modern browsers.

Typescript transpiler

What is Typescript translation? The Typescript transpiler plays a crucial role in the development process, converting Typescript code into Javascript. By doing so, it ensures compatibility with modern browsers, allowing developers to leverage the advantages of Typescript while still delivering applications that can run on various platforms. This transpilation process enables the utilization of advanced features offered by Typescript without compromising the ability to deploy applications widely and efficiently.

Let’s take a simple example. Suppose we’ve crafted a Typescript class named “Book” within the index.ts file, as outlined below.

  • .ts is the file extension for Typescript

  • If you haven’t installed Typescript on your computer yet, check this official documentation.

  • If you are not familiar with Typescript syntax, check out this official documentation.

// typescript
class Book{
 name: string;
 constructor(name:string){
   this.name = name;
 }
}

Now run tsc index.ts in the terminal to transpile our Book class. Once you do that, a new Javascript file will be generated with the same name in the same folder. This is the transpiled code.

Execute tsc index.ts in the terminal to transpile the Book class. Upon completion, a new Javascript file, retaining the same name, will emerge in the same folder. This file represents the transpiled code.

// javascript
var Book = /** @class */ (function () {
   function Book(name) {
    this.name = name;
   }
   return Book;
}());

The transpiled version is just Javascript code. So, it can be run on any modern browser.

Basic OOP concepts in Typescript

Typescript operates as an object-oriented programming (OOP) language, accommodating features like classes, interfaces, and inheritance. This section aims to revisit and reinforce our understanding of these fundamental OOP concepts in TypeScript.

Classes in Typescript

In Typescript, classes provide a blueprint for creating objects with shared properties and methods. Let’s delve into the details with examples.

Example 1: Basic Class

class Animal {
  name: string;

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

  makeSound(): void {
    console.log("Generic animal sound");
  }
}

// Creating an instance of the Animal class
const cat = new Animal("Cat");
console.log(cat.name);       // Output: Cat
cat.makeSound();             // Output: Generic animal sound

In this example, the Animal class has a property name and a method makeSound. The constructor initializes the name property when an instance is created.

Example 2: Inheritance

class Dog extends Animal {
  // Additional property specific to Dog
  breed: string;

  constructor(name: string, breed: string) {
    super(name);  // Calling the constructor of the base class
    this.breed = breed;
  }

  // Overriding the makeSound method
  makeSound(): void {
    console.log("Woof! Woof!");
  }
}

// Creating an instance of the Dog class
const germanShepherd = new Dog("Buddy", "German Shepherd");
console.log(germanShepherd.name);  // Output: Buddy
console.log(germanShepherd.breed); // Output: German Shepherd
germanShepherd.makeSound();        // Output: Woof! Woof!

Here, the Dog class extends the Animal class, inheriting its properties and methods. The super keyword is used to invoke the constructor of the base class.

Example 3: Access Modifiers

class Car {
  private model: string;

  constructor(model: string) {
    this.model = model;
  }

  protected startEngine(): void {
    console.log("Engine started");
  }

  public drive(): void {
    this.startEngine();
    console.log("Car is moving");
  }
}

// Creating an instance of the Car class
const myCar = new Car("Sedan");
myCar.drive();  // Output: Engine started \n Car is moving

In this example, the Car class demonstrates access modifiers. The private modifier restricts access to the model property outside the class, while the protected modifier allows access within the class and its subclasses. The public modifier denotes that the drive method is accessible from outside the class.

These examples showcase the fundamentals of Typescript classes, highlighting their versatility in encapsulating data and behavior within a structured and reusable format.

Typescript Interfaces

In TypeScript, interfaces define contracts for object shapes, providing a way to enforce a certain structure. Let’s explore TypeScript interfaces with few examples.

Example 1: Basic Interface

interface Person {
  firstName: string;
  lastName: string;
}

// Using the Person interface
const user: Person = {
  firstName: "John",
  lastName: "Doe"
};

console.log(user.firstName);  // Output: John
console.log(user.lastName);   // Output: Doe

Here, the Person interface specifies that any object implementing it must have firstName and lastName properties. The user object adheres to this interface.

Property validation in Typescript interface:

If you remove the firstName property from the Person object you will see the following error.

error TS2741: Property 'lastName' is missing in type '{ firstName: string; }' but required in type 'Person'.

Example 2: Optional Properties

interface Car {
  brand: string;
  model: string;
  year?: number;  // Optional property
}

const sedan: Car = {
  brand: "Toyota",
  model: "Camry"
};

console.log(sedan.year);  // Output: undefined

The year property in the Car interface is optional. Objects can conform to the interface with or without this property.

Example 3: Function in Interface

interface MathOperation {
  (x: number, y: number): number;
}

const add: MathOperation = (a, b) => a + b;
const multiply: MathOperation = (a, b) => a * b;

console.log(add(5, 3));       // Output: 8
console.log(multiply(2, 4));  // Output: 8

Interfaces can describe function types, allowing you to define the shape of functions. Here, the MathOperation interface represents a function that takes two numbers and returns a number.

Example 4: Interface Extending Another Interface

interface Employee {
  id: number;
  role: string;
}

interface DetailedEmployee extends Employee {
  department: string;
}

const manager: DetailedEmployee = {
  id: 101,
  role: "Manager",
  department: "HR"
};

console.log(manager.id);        // Output: 101
console.log(manager.role);      // Output: Manager
console.log(manager.department); // Output: HR

The DetailedEmployee interface extends the Employee interface, inheriting its properties. This ensures that objects conforming to DetailedEmployee also include the properties of Employee.

Example 5: Readonly Properties

interface ReadOnlyPerson {
  readonly firstName: string;
  readonly lastName: string;
}

const readOnlyUser: ReadOnlyPerson = {
  firstName: "Alice",
  lastName: "Smith"
};

// Uncommenting the line below will result in a compilation error
// readOnlyUser.firstName = "Bob";

Properties marked as readonly in an interface cannot be modified after the object is created. Attempting to modify a readonly property will result in a compilation error.

These examples showcase the flexibility and utility of TypeScript interfaces, enabling developers to define clear contracts for various elements in their code.

Behaviour validation in Typescript interface

In Angular, interfaces play a crucial role in defining contracts for components or services, ensuring that they adhere to specific shapes and have certain methods or properties. Let’s explore how you can use an interface to validate behavior in Angular with a simple example.

Consider a scenario where you have a service responsible for fetching user data from an API. You want to ensure that any service implementing this behavior adheres to a specific structure. Here’s how you can achieve this using an Angular interface:

// Interface defining the behavior for a user service
interface UserService {
  // Method to fetch user data based on user ID
  getUserData(userId: number): Promise<string>;
}

// Sample implementation of the UserService interface
class MyUserService implements UserService {
  async getUserData(userId: number): Promise<string> {
    // Simulate fetching user data from an API
    const userData = `User data for ID ${userId}`;
    return Promise.resolve(userData);
  }
}

// Another implementation that doesn't adhere to the interface
class InvalidUserService implements UserService {
  // Missing implementation for getUserData
}

In this example:
- We define an interface UserService with a method getUserData that takes a userId as a parameter and returns a Promise<string>. This represents the expected behavior for any service retrieving user data.

  • We then create a sample implementation (MyUserService) that adheres to the UserService interface. It provides a proper implementation for the getUserData method, fetching user data from a simulated API.

  • Additionally, we create an invalid implementation (InvalidUserService) that fails to provide an implementation for the required method. This demonstrates how interfaces help catch such issues during development.

By using interfaces, you can enforce a consistent structure for services, components, or other Angular constructs, ensuring that they follow the expected behavior. This helps in maintaining a clear and standardized codebase in your Angular application.

A few methods in Typescript arrays

Arrays are frequently used data structures in programming. In Typescript, a few methods are available to process elements in arrays. Let’s explore some important methods available on TypeScript arrays along with examples.

map() Method

The map() method creates a new array by applying a function to each element in the existing array.

const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = numbers.map((num) => num * 2);
console.log(doubledNumbers); // Output: [2, 4, 6, 8, 10]

filter() Method

The filter() method creates a new array with elements that pass a specified condition.

const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter((num) => num % 2 === 0);
console.log(evenNumbers); // Output: [2, 4]

reduce() Method

The reduce() method reduces the array to a single value by applying a function for each element.

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // Output: 15

forEach() Method

The forEach() method executes a provided function once for each array element.

const fruits = ['apple', 'banana', 'orange'];
fruits.forEach((fruit) => console.log(fruit));
// Output:
// apple
// banana
// orange

find() Method

The find() method returns the first element in the array that satisfies a provided testing function.

const numbers = [1, 2, 3, 4, 5];
const foundNumber = numbers.find((num) => num > 2);
console.log(foundNumber); // Output: 3

some() Method

The some() method tests whether at least one element in the array passes the test implemented by the provided function.

const numbers = [1, 2, 3, 4, 5];
const hasEven = numbers.some((num) => num % 2 === 0);
console.log(hasEven); // Output: true

These are just a few examples of the many methods available on TypeScript arrays. Understanding and utilizing these methods will enhance your ability to work with arrays effectively in TypeScript.

A few operators in Typescript

Let’s explore two important operators in TypeScript: the Spread (...) operator and the Double Exclamation (!!) operator.

Spread (...) Operator

The Spread operator is a versatile feature in TypeScript that allows you to expand elements in various contexts, such as arrays, objects, or function arguments.

Array Example

const originalArray = [1, 2, 3];
const newArray = [...originalArray, 4, 5];
console.log(newArray); // Output: [1, 2, 3, 4, 5]

Object Example

const originalObject = { name: 'John', age: 25 };
const newObject = { ...originalObject, city: 'New York' };

console.log(newObject);
// Output: { name: 'John', age: 25, city: 'New York' }

Function Argument Example

const greet = (name: string, ...messages: string[]) => {
  console.log(`Hello, ${name}!`);
  console.log(messages.join(' '));
};

greet('Alice', 'How are you?', 'Welcome!');
// Output:
// Hello, Alice!
// How are you? Welcome!
  • The Spread operator simplifies array and object manipulations and enhances the flexibility of function parameter handling.

  • The spread operator(…) doesn’t change the original array

  • Check more details on the spread operator here

Double Exclamation (!!) Operator

The Double Exclamation operator is a shorthand way of converting a value to its corresponding boolean representation. It’s often used for type assertion.

const someValue: any = 'Hello';
const booleanValue: boolean = !!someValue;
console.log(booleanValue); // Output: true

Here, !!someValue ensures that someValue is interpreted as a boolean. It is particularly useful when dealing with values that may have truthy or falsy nature.

Understanding these operators contributes to writing more concise and expressive TypeScript code. The Spread operator facilitates elegant data manipulation, while the Double Exclamation operator aids in ensuring accurate boolean representations.

  • Double exclamation returns the actual Boolean output of Truthy or Falsy values in Typescript.

  • List of Truthy values and list of Falsy values

Introduction to Develop Angular applications using Typescript

Now you know how Typescript applications work on modern browsers. Let’s move on to Angular. Angular is a dynamic web development framework introduced by Google. The first version was released in 2016. There are two different major versions of Angular known as Angularjs and Angular 2. Angularjs depends on Javascript. In other words, it supports ES5. Angular2 and later versions depend on Typescript. In other words, it supports ES6. Going forward, Angular will refer to Angular 2 in this tutorial.

Install Angular CLI

  • If you are not familiar with the basic Angular concepts, recommend you go over this official documentation.

Angular is available as an NPM package. Once you run npm install -g @angular/cli, the latest package will be downloaded into your computer. If you closely look at the command, you will see that it is not just Angular. We call it Angular CLI. Angular CLI is a fantastic tool to manage Angular applications. It automates almost all the manual tasks for us.

  • Check this setup guide for more details.

  • Going forward, we will use NPM to manage Angular application.

Generate a new Angular application

Once you have set up Angular CLI locally, you can generate a new Angular application running ng new <app-name> in the terminal. This command will generate all the required files and folders for us to begin with Angular. Not only that, it downloads all the required packages and stores them under the node_modules directory.

  • Find a complete guide for Angular files and folder structure here.

Now it’s time to run the Angular application. Just open the terminal in the project root folder and run ng serve -o. This command will do all the necessary things that are required to run this Angular application on the browser. At this point, you have a running Angular application. In the next tutorial, we will use this application for further development.

Conclusion

In conclusion, Typescript stands out as an optimized and user-friendly programming language, offering a seamless learning experience. While contemporary browsers may not directly support Typescript, the transpilation of Typescript into Javascript allows for its smooth integration with web applications. Angular, a dynamic web development framework crafted with Typescript, empowers developers to employ robust Object-Oriented Programming (OOP) techniques, fostering the creation of scalable and high-performance web applications. Thus, dedicating time to mastering Typescript’s syntax, understanding data structures, and embracing OOP concepts emerges as a valuable investment for forward-looking front-end developers.

Find the complete code on gitgub.


Comments


There are no comments yet.

Write a comment

You can use the Markdown syntax to format your comment.

  • Share: