DEV Community

José Miguel Álvarez Vañó
José Miguel Álvarez Vañó

Posted on • Updated on • Originally published at jmalvarez.dev

 

Singleton pattern in TypeScript

Introduction

The singleton pattern is a creational pattern that allows you to make sure that only one instance of a class is created.

Applicability

Use the Singleton pattern when:

  • it's important that your application only creates an instance of a class.
  • the same instance of a class should be use globally.

Implementation

You can find the full example source code here.

1. Declare a static property to hold the instance of the class. Remember that static properties are shared across all instances of a class.

In the example I'm going to apply the Singleton pattern to a class that represents a database connection.

class Database {
  private static instance: Database;
}
Enter fullscreen mode Exit fullscreen mode

2. Make the constructor of the class private so that it cannot be called from outside the class.

For the example, the constructor won't have any parameters. In a real-world scenario, you might want to pass some configuration to the constructor.

class Database {
  private static instance: Database;

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

3. Declare a static method that will be used to get the Singleton instance of the class. When the method is called for the first time,
it will create an instance of the class and store it in the static property. On subsequent calls, it will return the instance stored in the static property.

class Database {
  private static instance: Database;

  private constructor() {}

  public static getInstance(): Database {
    if (!Database.instance) {
      Database.instance = new Database();
    }

    return Database.instance;
  }
}
Enter fullscreen mode Exit fullscreen mode

4. The singleton instance can now be used from anywhere in the application. But first, I'll ad some business logic for the example.

class Database {
  private static instance: Database;

  private constructor() {}

  public static getInstance(): Database {
    if (!Database.instance) {
      Database.instance = new Database();
    }

    return Database.instance;
  }

  public query(sql: string): void {
    console.log(`Querying database: ${sql}`);
  }
}
Enter fullscreen mode Exit fullscreen mode

An example of how client code would use the Singleton instance:

const database = Database.getInstance();
database.query("SELECT * FROM users");

// Output:
// Querying database: SELECT * FROM users

const database2 = Database.getInstance();
if (database === database2) {
  console.log(
    "The same instance of Database was returned. The Singleton pattern works!"
  );
} else {
  console.log(
    "A new instance of Database was returned. The Singleton pattern failed."
  );
}

// Output:
// The same instance of Database was returned. The Singleton pattern works!
Enter fullscreen mode Exit fullscreen mode

Resources

Oldest comments (0)

The JavaScript Brief

1. Top 5 MERN STACK projects to improve your practical understanding

Boost your MERN Stack development skills by undertaking interesting beginner projects. These five engaging projects cover web applications and range from social media website applications to geo-social networking maps. Hone your understanding and apply modern techniques backed up by hands-on experience.

2. How To Optimize Your React App’s Performance

Learn the best optimizing techniques to make your React applications faster and more efficient. Focusing on the identification of performance bottlenecks and common pitfalls to avoid, these optimization strategies will keep your applications running smoothly even when faced with growing complexity.

3. A story of let, const, object mutation, and a bug in my code

In the pursuit of bug-free code, explore an incident involving a mix-up between const and let, making sure your custom code works effectively with third

party documentation. Discover best practices on program flow and learn about JavaScript's unpredictable aspects to ensure your core code is robust.