Objects in TypeScript
Placement-ready Courses: Enroll Now, Thank us Later!
One of the core concepts of TypeScript is objects, which represent data structures in a program.
In TypeScript, objects are instances of a class, which defines their properties and methods. Defining a class is the first step in creating an object. Here is an example of a class definition:
class DataFlair_Person {
firstName: string;
lastName: string;
constructor(firstName: string, lastName: string) {
this.firstName = firstName;
this.lastName = lastName;
}
getFullName(): string {
return `${this.firstName} ${this.lastName}`;
}
}
In this example, we define a class called DataFlair_Person with two properties, firstName and lastName, and one method, getFullName(). The constructor function takes two arguments, firstName and lastName, and initializes the object’s properties.
To create an object of this class, we use the new keyword:
const person = new DataFlair_Person('John', 'Doe');
This creates a new DataFlair_Person class object with the firstName property set to ‘John’ and the lastName property set to ‘Doe.’
Once you have created an object, you can access its properties and methods using the dot notation:
console.log(person.firstName); // 'John' console.log(person.lastName); // 'Doe' console.log(person.getFullName()); // 'John Doe'
In TypeScript, objects can also be defined using interfaces. An interface is a contract that defines the shape of an object, but it does not provide an implementation. Here is an example of an interface definition:
interface DataFlair_Animal {
name: string;
species: string;
makeSound(): void;
}
In this example, we define a DataFlair_Animal interface with three properties: name, species, and makeSound(). The makeSound() method does not return anything (void).
To create an object that implements this interface, we define an object literal that has the same properties and methods:
const dog: DataFlair_Animal = {
name: 'Rufus',
species: 'Dog',
makeSound() {
console.log('Woof!');
},
};
This creates a dog object with the name property set to ‘Rufus.’ The species property set to ‘Dog,’ and the makeSound() method logs ‘Woof!’ to the console.
To work with objects in TypeScript, it’s important to understand some key concepts related to objects, including inheritance, encapsulation, and polymorphism.
Inheritance in TypeScript
Inheritance is the process by which one class can inherit the properties and methods of another class. In TypeScript, inheritance is achieved using the extends keyword. This is an example of a class hierarchy:
class DataFlair_Animal {
name: string;
constructor(name: string) {
this.name = name;
}
makeSound(): void {
console.log('Generic animal sound');
}
}
class Dog extends DataFlair_Animal {
makeSound(): void {
console.log('Woof!');
}
}
In this example, we define a base class called DataFlair_Animal with a name property and a makeSound() method. We then define a subclass called Dog that extends the DataFlair_Animal class and overrides the makeSound() method to log ‘Woof!’ to the console.
Encapsulation in TypeScript
Encapsulation is the process of hiding data from outside access to ensure data integrity and security. In TypeScript, encapsulation is achieved by private or protected properties and methods. Here is an example of a class with private and protected properties:
class DataFlair_BankAccount {
private accountNumber: string;
protected balance: number;
constructor(accountNumber: string, balance: number) {
this.accountNumber = accountNumber;
this.balance = balance;
}
deposit(amount: number): void {
this.balance += amount;
}
withdraw(amount: number): void {
if (this.balance >= amount) {
this.balance -= amount;
} else {
console.log('Insufficient funds');
}
}
}
class SavingsAccount extends DataFlair_BankAccount {
private interestRate: number;
constructor(accountNumber: string, balance: number, interestRate: number) {
super(accountNumber, balance);
this.interestRate = interestRate;
}
addInterest(): void {
const interest = this.balance * (this.interestRate / 100);
this.deposit(interest);
}
}
In this example, we define a DataFlair_BankAccount class with a private accountNumber property and a protected balance property. We also define a deposit() method that adds funds to the account and a withdraw() method that subtracts funds from the account. We then define a SavingsAccount class that extends the BankAccount class. It adds a private interestRate property and an addInterest() method that calculates and adds interest to the account.
Polymorphism in TypeScript
Polymorphism is the process by which one object can take on many forms. In TypeScript, polymorphism is achieved through method overriding and method overloading. Method overriding occurs when a subclass provides a specific implementation of a method already provided by its parent class. When a class has numerous methods with the same name but different parameters, this is known as method overloading. Here is an illustration of a method override:
class DataFlair_Shape {
draw(): void {
console.log('Drawing a generic shape');
}
}
class Circle extends DataFlair_Shape {
draw(): void {
console.log('Drawing a circle');
}
}
In this example, we define a DataFlair_Shape class with a draw() method that logs ‘Drawing a generic shape’ to the console. We then define a Circle class that extends the DataFlair_Shape class and overrides the draw() method to log ‘Drawing a circle’ to the console.
Object Template
Templates in objects, also known as generic types, are a feature in TypeScript that allows a class or function to work with different types of data without specifying the type at compile-time.
Templates are defined using angle brackets (<>) and can be used to declare a type parameter for a class or function. The type parameter can then be used within the class or function to create a generic implementation that works with any type that meets certain requirements.
Here is an example of using templates in TypeScript:
class DataFlair_Stack<T> {
private items: T[] = [];
push(item: T) {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
}
const numberStack = new DataFlair_Stack<number>();
numberStack.push(1);
numberStack.push(2);
console.log(numberStack.pop());
const stringStack = new DataFlair_Stack<string>();
stringStack.push('Hello');
stringStack.push('World');
console.log(stringStack.pop());
Output –
World
In this example, the “DataFlair_Stack” class uses a type parameter “T” to allow the class to work with any type of data. The “push” method takes a parameter of type “T” and adds it to the “items” array, while the “pop” method returns a value of type “T” from the end of the “items” array. The type parameter “T” is defined when creating a new instance of the “DataFlair_Stack” class, allowing the class to work with different types of data depending on the context.
Templates in objects are a powerful tool for creating reusable and generic code that can work with a wide range of data types. They provide a flexible and type-safe way to work with data in TypeScript, making them an important language feature for developing scalable and maintainable applications.
Duck-typing in TypeScript
Duck typing is a type system used in TypeScript that determines the type of an object based on its behavior or methods rather than its class or interface definition. In other words, if an object walks like a duck and quacks like a duck, it is a duck.
Duck typing allows TypeScript to be more flexible and dynamic when working with objects, enabling them to be used interchangeably as long as they have the same properties and methods. This can be particularly useful when working with objects with similar but not identical interfaces or with objects created dynamically at runtime.
Here is an example of duck typing in TypeScript:
interface DataFlair_Person {
name: string;
age: number;
}
function printPerson(person: DataFlair_Person) {
console.log(`Name: ${person.name}, Age: ${person.age}`);
}
const alice = { name: 'Alice', age: 25 };
const bob = { name: 'Bob', age: 30, gender: 'male' };
printPerson(alice);
printPerson(bob);
Output –
Name: Bob, Age: 30
In this example, the “printPerson” function takes an object of type “DataFlair_Person” as its parameter. However, the “bob” object does not explicitly implement the “Person” interface, as it has an additional “gender” property. Nevertheless, the “bob” object is still considered to be of type “DataFlair_Person” by TypeScript’s duck typing rules, as it has the same “name” and “age” properties as the “Person” interface.
Duck typing can be a powerful tool for writing flexible and dynamic code in TypeScript. It allows objects to be used interchangeably based on their behavior rather than their explicit type definition. However, it can also lead to errors or unexpected behavior if objects with similar but not identical interfaces are used interchangeably. Therefore, it is important to use duck typing judiciously and with careful consideration of the objects being used.
Conclusion
In conclusion, TypeScript provides powerful features for working with objects, including inheritance, encapsulation, polymorphism, and interfaces. These features help developers write more maintainable, reusable, and scalable code by ensuring that objects are well-organized, secure, and easy to extend and modify. By mastering these concepts, developers can create sophisticated and robust applications that meet the needs of their users and stakeholders.
Did we exceed your expectations?
If Yes, share your valuable feedback on Google

