Typescript Icon Get 42% off the TypeScript bundle

See the bundle then add to cart and your discount is applied.

0 days
00 hours
00 mins
00 secs

Write TypeScript like a pro. Typescript Icon

Follow the ultimate TypeScript roadmap.

Abstract Classes in TypeScript

In this post you’ll learn how to create and use an abstract class in TypeScript.

Abstract classes don’t exist as part of the JavaScript language, they are a specific TypeScript feature.

The short answer is when you see the word abstract you never call that class directly - you only inherit from it. It is essentially a naming convention given to a class in TypeScript that says “only inherit from me”. If you try and call that class directly, TypeScript will throw an error and not let you as it is marked as abstract.

Before we demonstrate an abstract class, let’s take a simple example without it being abstract:

class Product {
  name: string;
  price: number;
  constructor(name: string, price: number) {
    this.name = name;
    this.price = price;
  }
}

Our Product class allows us to create a basic product shape, which we can invoke multiple times to create new products:

const espresso = new Product('Espresso', 399);
const toastie = new Product('Toastie', 599);

Simple, yet effective.

But now let’s say our product needs to get a little more complex and deviate in features slightly, we might want to attach some custom metadata to each class to split it up into categories:

class Product {
  name: string;
  price: number;
  category: 'food' | 'drink';
  constructor(name: string, price: number, category: 'food' | 'drink') {
    this.name = name;
    this.price = price;
    this.category = category;
  }
}

This is a simple example, but imagine a more advanced scenario, this is where abstract classes can help us.

Let’s make our class abstract via the keyword before the class identifier:

abstract class Product {
  name: string;
  price: number;
  category: 'food' | 'drink';
  constructor(name: string, price: number, category: 'food' | 'drink') {
    this.name = name;
    this.price = price;
    this.category = category;
  }
}

Now, we cannot call Product directly, otherwise we would see an error such as “Cannot create an instance of an abstract class.”

Instead, we have to create a new class that inherits the functionality using the extends keyword:

class Food extends Product {
  constructor(name: string, price: number) {
    super(name, price, 'food');
  }
}

class Drink extends Product {
  constructor(name: string, price: number) {
    super(name, price, 'drink');
  }
}

This creates two new classes that extend the base class of Product, which we then set the 'food' or 'drink' flag inside the constructor.

Note here that we are calling super() which allows us to pass in our name and price parameters from our Food or Drink class into the abstract class Product.

All other functionality is inherited, so our classes automatically inherit name, price, category properties and any other methods that may exist on the abstract class.

Abstract classes in TypeScript are more of a design feature than a functionality feature, in reality they provide nothing more than a regular class does when it comes to inheriting functionality, except we cannot call the class directly.

🏆 Check out my series of TypeScript Courses where you’ll learn TypeScript in-depth with real-world scenarios and examples to supercharge your JavaScript development.

So remember: if you see abstract class, you can only extend from it and not use it alone.

And that’s it! Abstract classes in TypeScript, how to create your own and how they differ to a standard class.

Use them wisely to design your class logic and create more type-safe code. It helps when working on teams as well, as developers will automatically not be able to use your abstract classes directly, so they act more as self-documenting.

Learn TypeScript the right way.

The most complete guide to learning TypeScript ever built.
Trusted by 82,951 students.

Todd Motto

with Todd Motto

Google Developer Expert icon Google Developer Expert

Related blogs 🚀

Free eBooks:

Angular Directives In-Depth eBook Cover

JavaScript Array Methods eBook Cover

NestJS Build a RESTful CRUD API eBook Cover