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 theUserService
interface. It provides a proper implementation for thegetUserData
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 about the spread operator on developer.mozilla.org
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.
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 on angular.io.
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.