TypeScript Interface vs. Class: What’s Difference?

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.

FeatureClassesInterfaces
PurposeDefine structure and implement behavior.Solely define structure without implementation.
Access ModifiersSupport access modifiers (public, private, protected).Cannot contain access modifiers.
ConstructorCan have constructors.Cannot have constructors.
Instance CreationInstances can be created using new keyword.Cannot be instantiated directly.
Static MembersCan have static properties and methods.Cannot contain static members.
Partial ImplementationRequire implementation of all defined methods.Allow for optional properties and methods.
Runtime ExistenceExist 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

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.