Classes vs Interfaces in TypeScript - What's the Difference?

Learn Key Differences Between Classes and Interfaces in TypeScript

ยท

4 min read

Classes vs interface in TypeScript

Classes and interfaces are fundamental building blocks in TypeScript. While they have some similarities, they serve different purposes. This post explains the key differences between classes and interfaces in TypeScript with examples.

Why Classes and Interfaces Matter in TypeScript

Understanding how classes and interfaces work in TypeScript is important for a few reasons:

  • Classes allow you to create objects with data and behavior. Interfaces define contracts for what classes must be implemented.

  • TypeScript's type system relies heavily on classes and interfaces to provide static typing.

  • Knowing when to use classes versus interfaces will help you write cleaner, more maintainable TypeScript code.

Class Overview

Classes are like blueprints for creating objects in JavaScript. They're great when you want to make something with both data and actions attached to it. Think of them as a way to bundle together the characteristics (data) and behaviors (actions) of something.

Example: Imagine you're building an app, and you want to represent people in it. You can use a class called "Person" to store details like a person's name and age. It's like creating a template for people, where you can also define what they can do, like say hello or introduce themselves.

Class Example

class Person {
  // Properties
  name: string;

  // Constructor
  constructor(name: string) {
    // Initialize the 'name' property with the provided name.
    this.name = name;
  }

  // Method
  sayHello() {
    // Display a greeting message including the 'name' property.
    console.log(`Hello, my name is ${this.name}`);
  }
}

// Create a new Person object with the name "Alice".
const person1 = new Person("Alice");
// Call the 'sayHello' method to introduce the person.
person1.sayHello(); // Outputs: Hello, my name is Alice
  • Purpose: Classes are used when you want to create instances (objects) of a specific type that have both data and behavior associated with them.

  • Instance Creation: You can create instances of classes using the new keyword.

  • Implementation: Classes contain the implementation of methods and properties.

  • Inheritance: Classes support inheritance using extends.

  • Constructor: Classes can have constructors that run on instantiation.

  • Access Modifiers: Properties and methods can have modifiers like public and private.

Interface Overview

Interfaces are like contracts in JavaScript. They define what something should look like, but they don't provide the actual content. They're perfect when you want to ensure that different parts of your code follow the same structure.

Example: Suppose you have different types of animals in your app, like dogs and cats. You can use an interface called "Animal" to say that every animal should have a name and be able to make a sound. However, the interface doesn't tell you how a specific animal makes a sound; it just says they should be able to do it.

Interface Example

interface Animal {
  // Property: Name of the animal.
  name: string;

  // Method: Make a sound specific to the animal.
  makeSound(): void; 
}

class Dog implements Animal {
  // Property: Name of the dog.
  name: string;

  // Constructor
  constructor(name: string) {
    // Initialize the 'name' property with the provided name.
    this.name = name;  
  }

  // Implement the 'makeSound' method for a dog.
  makeSound() {
    // Display a barking sound along with the dog's name.
    console.log(`${this.name} barks`);
  }
}

// Create a new Dog object named "Buddy."
const myDog = new Dog("Buddy");
// Call the 'makeSound' method to hear the dog bark.
myDog.makeSound(); // Outputs: Buddy barks
  • Purpose: Interfaces define the structure and contract for classes.

  • Instance Creation: You cannot instantiate interfaces directly.

  • Implementation: Interfaces only declare structure, not implementation.

  • Inheritance: Interfaces support declaration merging.

  • Constructor: Interfaces cannot have constructors.

  • Access Modifiers: Interfaces do not have access modifiers.

Comparison of Classes vs. Interfaces

PointClassesInterfaces
PurposeInstantiate objectsDefine contracts for structure
Instance creationUse new keywordCannot instantiate directly
ImplementationContains implementationJust declarations, no implementation
InheritanceExtends classesDeclaration merging
ConstructorHas constructorNo constructor
Access modifiersHas public, private, etc.No access modifiers
Optional propertiesNot supportedCan mark optional properties with ?

At Last, this is a bonus learning for you

// Define an interface with an optional property.
interface Person {
  name: string;
  age?: number; // '?' indicates that 'age' is optional
}

// Create objects conforming to the 'Person' interface.
const person1: Person = { name: "Alice" };
const person2: Person = { name: "Bob", age: 30 };

console.log(person1); // Outputs: { name: 'Alice' }
console.log(person2); // Outputs: { name: 'Bob', age: 30 }

This code demonstrates how you can use the ? symbol to specify that a property in an interface is optional.

Summary

Classes and interfaces serve different roles in TypeScript. Classes are used to create objects with data and behaviors, while interfaces enforce contracts on structure and behavior. Understanding when to use each will help you leverage types effectively.

Did you find this article valuable?

Support Mikey's Blog by becoming a sponsor. Any amount is appreciated!

ย