Skip to main content

What are Interfaces In TypeScript

ยท 6 min read

An interface can be thought of as a blueprint for an object or a class, specifying the properties and methods that must be implemented.

What are Interfaces ๐Ÿค”โ€‹

Interfaces in TypeScript are a powerful way to define contracts within your code, which help to ensure that the structure and types of objects or classes are consistent across your application. They are used to define the shape and properties of an object or a class, and to enforce the implementation of certain methods in a class.

An interface can be thought of as a blueprint for an object or a class, specifying the properties and methods that must be implemented. When an object or a class implements an interface, it must provide a concrete implementation of all the properties and methods defined in the interface.

Interfaces can be used for various purposes in TypeScript, such as:

  1. Defining the shape of an object: Interfaces can be used to define the structure of an object, ensuring that it has specific properties with the appropriate types. This can be useful when working with objects that are expected to adhere to a specific structure throughout the application.

  2. Enforcing implementation of certain methods in a class: Interfaces can be used to specify methods that a class must implement. This is useful when creating a group of classes that should have a consistent set of methods, such as implementing a particular design pattern.

  3. Extending interfaces: Interfaces can extend other interfaces, allowing you to create more complex and specific contracts for your code.

Here's an example of an interface in TypeScript:

Let us assume that we need to have a class that generates a Car object which has a make, model, and year properties like so:

const car = {
make: "Toyota",
model: "Camry",
year: 2022,
};

In this example, the Vehicle interface defines a contract that includes three properties (make, model, and year) and two methods (startEngine and stopEngine). The Car class implements the Vehicle interface, ensuring that it provides concrete implementations for all the properties and methods specified in the interface.

interface Vehicle {
make: string;
model: string;
year: number;

startEngine(): void;

stopEngine(): void;
}

class Car implements Vehicle {
constructor(public make: string, public model: string, public year: number) {}

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

stopEngine(): void {
console.log("Engine stopped.");
}
}

The make, model, and year properties are defined directly in the constructor using the public access modifier. This simplifies the class definition, as there is no need to explicitly declare the properties separately and then assign them within the constructor.

TypeScript Course Instructor Image
TypeScript Course Instructor Image

Time To Transition From JavaScript To TypeScript

Level Up Your TypeScript And Object Oriented Programming Skills. The only complete TypeScript course on the marketplace you building TypeScript apps like a PRO.

SEE COURSE DETAILS

Inheritance With Interfacesโ€‹

One of the biggest advantages of using interfaces in TypeScript is that they allow for a flexible and scalable way to define contracts for multiple classes. This is achieved through the following features:

Single interface, single classโ€‹

The concept of single interface, single class refers to the scenario where an interface is implemented by only one class. This approach might be less common compared to using a single interface with multiple classes, but it can still provide benefits in terms of code organization and maintainability.

When you have a single interface implemented by a single class, the interface still acts as a contract, specifying the required properties and methods that the class must implement. This ensures that the class adheres to a specific structure and behavior. What we looked in the above code was an example of Single interface that is Vehicle implemented by a single class Car.

Single interface, multiple classesโ€‹

A single interface can be implemented by multiple classes. This ensures that all the classes that implement the interface follow the same contract, providing a consistent structure and behavior throughout the application. This is especially helpful when dealing with a group of related classes that should have common properties and methods.

Multiple interfaces, single classโ€‹

A class can implement multiple interfaces, allowing it to inherit properties and methods from more than one interface. This provides a level of flexibility that is not possible with single inheritance in classical object-oriented programming. By implementing multiple interfaces, a class can be a part of several different contracts, which makes the code more modular and easier to maintain.

These features enable a high degree of code reusability, consistency, and modularity, which are essential in developing scalable and maintainable applications.

Example: Single interface, multiple classesโ€‹

Let's create another class called Motorcycle that also implements the Vehicle interface, illustrating that the interface can be used for multiple classes with similar properties and methods. Here's the updated code:

class Motorcycle implements Vehicle {
constructor(public make: string, public model: string, public year: number) {}

startEngine(): void {
console.log("Motorcycle engine started.");
}

stopEngine(): void {
console.log("Motorcycle engine stopped.");
}
}

const myMotorcycle = new Motorcycle("Honda", "CBR600RR", 2021);

console.log(myMotorcycle);

In this example, we added a Motorcycle class that also implements the Vehicle interface. Both the Car and Motorcycle classes have the properties make, model, and year, as well as the methods startEngine and stopEngine.

The console output would look like this:

Motorcycle {
make: 'Honda',
model: 'CBR600RR',
year: 2021
}

Example: Multiple interfaces, single classโ€‹

As shown, the Vehicle interface is used to create different classes (in this case, Car and Motorcycle) with similar properties and methods, ensuring consistency and adherence to a specific structure throughout the application.

To demonstrate the concept of multiple interfaces being implemented by a single class, let's create a new interface called Inspectable that includes a method inspect(). Then, we'll update the Car class to implement both the Vehicle and Inspectable interfaces:

interface Inspectable {
inspect(): void;
}

class Car implements Vehicle, Inspectable {
constructor(public make: string, public model: string, public year: number) {}

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

stopEngine(): void {
console.log("Engine stopped.");
}

inspect(): void {
console.log(`Inspecting ${this.year} ${this.make} ${this.model}.`);
}
}

const myCar = new Car("Toyota", "Camry", 2022);
myCar.inspect();

In this example, we created a new interface called Inspectable with a single method inspect(). We then updated the Car class to implement both the Vehicle and Inspectable interfaces. This means the Car class must now provide implementations for all the properties and methods specified in both interfaces.

The inspect() method has been added to the Car class, and when we create an instance of Car and call the inspect() method, we'll see the following output in the console:

Inspecting 2022 Toyota Camry.

This example demonstrates how a single class (Car) can implement multiple interfaces (Vehicle and Inspectable), inheriting properties and methods from each interface and creating a more versatile and modular class.

What Can You Do Next ๐Ÿ™๐Ÿ˜Šโ€‹

If you liked the article, consider subscribing to Cloudaffle, my YouTube Channel, where I keep posting in-depth tutorials and all edutainment stuff for ssoftware developers.

YouTube @cloudaffle