Similar to other object-oriented programming languages (such as Java), TypeScript supports interfaces and classes to define the structure and behavior of the runtime objects. We can use an interface and/or a class to encapsulate the data and the behavior of objects, but both serve different purposes.
Interfaces primarily define the abstract contracts for objects (fields and method definitions); whereas classes allow both contract definition and implementation (fields and method implementations).
1. Syntax
Let us start with revisiting the syntax for creating a simple interface and a class. In the following example, we have created interface Vehicle that has data (brand) and abstraction of behavior (start() method). The Car class implements the Vehicle interface and implements the start() method by giving it a body to execute.
// Interface
interface Vehicle {
brand: string;
start(): void;
}
// Class
class Car {
brand: string;
constructor(brand: string) {
this.brand = brand;
}
start() {
console.log(`${this.brand} started.`);
}
}
2. Inheritance
The classes and interfaces, in TypeScript, support inheritance i.e. creating a child by extending the parent. But the difference is that a class can only extend from a single parent class but an interface can extend from multiple interfaces.
In the following example, the HybridVehicle extends two interfaces PetrolVehicle and ElectricVehicle.
interface Vehicle {
brand: string;
start(): void;
stop(): void;
}
interface PetrolVehicle extends Vehicle {
refillFuel(): void;
}
interface ElectricVehicle extends Vehicle {
charge(): void;
}
interface HybridVehicle extends PetrolVehicle, ElectricVehicle {
changeMode(): void;
}
But when we try the similar things using classes, we are not allowed. We get the error that “Classes can only extend a single class“.
class PetrolCar implements PetrolVehicle {
brand: string;
constructor(brand: string) {
this.brand = brand;
}
start() {
console.log(`${this.brand} started.`);
}
refillFuel() {
console.log(`${this.brand} refilled.`);
}
}
class ElectricCar implements ElectricVehicle {
brand: string;
constructor(brand: string) {
this.brand = brand;
}
start() {
console.log(`${this.brand} started.`);
}
charge() {
console.log(`${this.brand} charged.`);
}
}
// Error: Classes can only extend a single class.
class HybridCar extends PetrolCar, ElectricCar {
// ...
}
3. Access Modifiers
The classes can have access modifiers like public
, private
, and protected
to control the visibility of properties and methods.
On the other hand, interfaces cannot contain access modifiers because they only describe the structure, not the implementation.
// Interface
interface Vehicle {
public brand: string; // Error: 'public' modifier cannot appear on a type member.
public start(): void; // Error: 'public' modifier cannot appear on a type member.
}
// Class
class Car {
public brand: string; // OK
constructor(brand: string) {
this.brand = brand;
}
public start() { //OK
console.log(`${this.brand} started.`);
}
}
4. Constructor
Classes can have constructors that runs automatically when an instance is created. Interfaces cannot have a constructor because they are purely for describing types.
We can see in the previous code example that Car has a constructor, and the interface does not.
5. Static Members
In TypeScript, a class can have static properties and methods that belong to the class itself, not instances. But an interface cannot contain static members because it describes only the instance shape.
// Class
class Car {
static tyres: 4; // OK
}
// Interface
interface Vehicle {
static tyres: 4; // 'static' modifier cannot appear on a type member.
}
6. Runtime Existence
The classes are runtime entity. After we compile the ‘.ts‘ files, the classes are converted into equivalent JavaScript objects.
The interfaces are only for abstraction and type checking, so they are discarded from the generated Javascript files.
7. Summary
Let us list down the above discussed differences between an interface and a class in TypeScript.
Feature | Classes | Interfaces |
---|---|---|
Purpose | Define structure and implement behavior. | Solely define structure without implementation. |
Access Modifiers | Support access modifiers (public, private, protected). | Cannot contain access modifiers. |
Constructor | Can have constructors. | Cannot have constructors. |
Instance Creation | Instances can be created using new keyword. | Cannot be instantiated directly. |
Static Members | Can have static properties and methods. | Cannot contain static members. |
Partial Implementation | Require implementation of all defined methods. | Allow for optional properties and methods. |
Runtime Existence | Exist at runtime, contribute to generated JavaScript code. | Are erased during compilation, do not exist in JavaScript. |
8. Conclusion
This short tutorial discussed the most basic differences between a class and an interface in Typescript. We discussed the differences within syntax, extensibility, usage and generated code after compilation with examples.
Happy Learning !!
Comments