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.