Singleton classes with Typescript

Thales Bruno - Nov 9 '23 - - Dev Community

In this post, we will learn how to create a singleton class using Typescript.

Singleton pattern

The Singleton design pattern is a very well-known pattern used in software engineering that ensures we only have one instance, or a single instance, of a class in our application and also provides an easy way to get access to that object.

Implementation

In order to implement a Singleton class we basically need to follow these two steps:

  1. Make the class constructor private, preventing from using the new operator to create objects of that class.
  2. Create a static method to instantiate our single instance and make it accessible through the application.

Here's a Lonely class which implements the singleton pattern:

class Lonely {
  private static instance: Lonely;

  private constructor() {}

  static getInstance() {
    if (this.instance) {
      return this.instance;
    }
    this.instance = new Lonely();
    return this.instance;
  }
}
Enter fullscreen mode Exit fullscreen mode

Breaking down the code:

First, we define an instance property:

private static instance: Lonely;
Enter fullscreen mode Exit fullscreen mode

This property holds the single instance of our Lonely class. It's private and static since it shouldn't be accessible from its objects (or from its only object in our singleton case).

Then, we have the constructor:

private constructor() {}
Enter fullscreen mode Exit fullscreen mode

This is one of the key pieces where we make the constructor private, so if we try to instantiate new object of Lonely with const newInstance = new Lonely() we get an error: Constructor of class 'Lonely' is private and only accessible within the class declaration.

And finally, we have the getInstance method.

  static getInstance() {
    if (this.instance) {
      return this.instance;
    }
    this.instance = new Lonely();
    return this.instance;
  }
Enter fullscreen mode Exit fullscreen mode

We don't need to name it getInstance but it's a good practice following the naming convention so it helps our code to be widely understandable.

What we must do is make it static and public, since it will be the point of access to creating the single instance of our class.

The logic is pretty simple: if we already have an instance of our class we just return it; if it's the first instantiation then we create our object calling the private constructor new Lonely() and return it.

We could also use the Lonely class name instead of the this keyword:

  static getInstance() {
    if (Lonely.instance) {
      return Lonely.instance;
    }
    Lonely.instance = new Lonely();
    return Lonely.instance;
  }
Enter fullscreen mode Exit fullscreen mode

Accessing our single instance

To access the only object of our Lonely class we just need to call its getInstance method:

const l1 = Lonely.getInstance();
const l2 = Lonely.getInstance();

console.log(l1 === l2); // return true
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . .
Terabox Video Player