[singleton] How to define Singleton in TypeScript

What is the best and most convenient way to implement a Singleton pattern for a class in TypeScript? (Both with and without lazy initialisation).

This question is related to singleton typescript

The answer is


The following approach creates a Singleton class that can be used exacly like a conventional class:

class Singleton {
    private static instance: Singleton;
    //Assign "new Singleton()" here to avoid lazy initialisation

    constructor() {
        if (Singleton.instance) {
            return Singleton.instance;
        }

        this. member = 0;
        Singleton.instance = this;
    }

    member: number;
}

Each new Singleton() operation will return the same instance. This can however be unexpected by the user.

The following example is more transparent to the user but requires a different usage:

class Singleton {
    private static instance: Singleton;
    //Assign "new Singleton()" here to avoid lazy initialisation

    constructor() {
        if (Singleton.instance) {
            throw new Error("Error - use Singleton.getInstance()");
        }
        this.member = 0;
    }

    static getInstance(): Singleton {
        Singleton.instance = Singleton.instance || new Singleton();
        return Singleton.instance;
    }

    member: number;
}

Usage: var obj = Singleton.getInstance();


Here is yet another way to do it with a more conventional javascript approach using an IFFE:

module App.Counter {
    export var Instance = (() => {
        var i = 0;
        return {
            increment: (): void => {
                i++;
            },
            getCount: (): number => {
                return i;
            }
        }
    })();
}

module App {
    export function countStuff() {
        App.Counter.Instance.increment();
        App.Counter.Instance.increment();
        alert(App.Counter.Instance.getCount());
    }
}

App.countStuff();

View a demo


In Typescript, one doesn't necessarily have to follow the new instance() Singleton methodology. An imported, constructor-less static class can work equally as well.

Consider:

export class YourSingleton {

   public static foo:bar;

   public static initialise(_initVars:any):void {
     YourSingleton.foo = _initvars.foo;
   }

   public static doThing():bar {
     return YourSingleton.foo
   }
}

You can import the class and refer to YourSingleton.doThing() in any other class. But remember, because this is a static class, it has no constructor so I usually use an intialise() method that is called from a class that imports the Singleton:

import {YourSingleton} from 'singleton.ts';

YourSingleton.initialise(params);
let _result:bar = YourSingleton.doThing();

Don't forget that in a static class, every method and variable needs to also be static so instead of this you would use the full class name YourSingleton.


I am surprised not to see the following pattern here, which actually looks very simple.

// shout.ts
class ShoutSingleton {
  helloWorld() { return 'hi'; }
}

export let Shout = new ShoutSingleton();

Usage

import { Shout } from './shout';
Shout.helloWorld();

i think maybe use generics be batter

class Singleton<T>{
    public static Instance<T>(c: {new(): T; }) : T{
        if (this._instance == null){
            this._instance = new c();
        }
        return this._instance;
    }

    private static _instance = null;
}

how to use

step1

class MapManager extends Singleton<MapManager>{
     //do something
     public init():void{ //do }
}

step2

    MapManager.Instance(MapManager).init();

This is probably the longest process to make a singleton in typescript, but in larger applications is the one that has worked better for me.

First you need a Singleton class in, let's say, "./utils/Singleton.ts":

module utils {
    export class Singleton {
        private _initialized: boolean;

        private _setSingleton(): void {
            if (this._initialized) throw Error('Singleton is already initialized.');
            this._initialized = true;
        }

        get setSingleton() { return this._setSingleton; }
    }
}

Now imagine you need a Router singleton "./navigation/Router.ts":

/// <reference path="../utils/Singleton.ts" />

module navigation {
    class RouterClass extends utils.Singleton {
        // NOTICE RouterClass extends from utils.Singleton
        // and that it isn't exportable.

        private _init(): void {
            // This method will be your "construtor" now,
            // to avoid double initialization, don't forget
            // the parent class setSingleton method!.
            this.setSingleton();

            // Initialization stuff.
        }

        // Expose _init method.
        get init { return this.init; }
    }

    // THIS IS IT!! Export a new RouterClass, that no
    // one can instantiate ever again!.
    export var Router: RouterClass = new RouterClass();
}

Nice!, now initialize or import wherever you need:

/// <reference path="./navigation/Router.ts" />

import router = navigation.Router;

router.init();
router.init(); // Throws error!.

The nice thing about doing singletons this way is that you still use all the beauty of typescript classes, it gives you nice intellisense, the singleton logic keeps someway separated and it's easy to remove if needed.


Add the following 6 lines to any class to make it "Singleton".

class MySingleton
{
    private constructor(){ /* ... */}
    private static _instance: MySingleton;
    public static getInstance(): MySingleton
    {
        return this._instance || (this._instance = new this());
    };
}

Test example:

var test = MySingleton.getInstance(); // will create the first instance
var test2 = MySingleton.getInstance(); // will return the first instance
alert(test === test2); // true

[Edit]: Use Alex answer if you prefer to get the instance through a property rather a method.


After scouring this thread and playing around with all the options above - I settled with a Singleton that can be created with proper constructors:

export default class Singleton {
  private static _instance: Singleton

  public static get instance(): Singleton {
    return Singleton._instance
  }

  constructor(...args: string[]) {
    // Initial setup

    Singleton._instance = this
  }

  work() { /* example */ }

}

It would require an initial setup (in main.ts, or index.ts), which can easily be implemented by
new Singleton(/* PARAMS */)

Then, anywhere in your code, just call Singleton.instnace; in this case, to get work done, I would call Singleton.instance.work()


This is the simplest way

class YourSingletoneClass {
  private static instance: YourSingletoneClass;

  private constructor(public ifYouHaveAnyParams: string) {

  }
  static getInstance() {
    if(!YourSingletoneClass.instance) {
      YourSingletoneClass.instance = new YourSingletoneClass('If you have any params');
    }
    return YourSingletoneClass.instance;
  }
}

You can also make use of the function Object.Freeze(). Its simple and easy:

class Singleton {

  instance: any = null;
  data: any = {} // store data in here

  constructor() {
    if (!this.instance) {
      this.instance = this;
    }
    return this.instance
  }
}

const singleton: Singleton = new Singleton();
Object.freeze(singleton);

export default singleton;

Not a pure singleton (initialization may be not lazy), but similar pattern with help of namespaces.

namespace MyClass
{
    class _MyClass
    {
    ...
    }
    export const instance: _MyClass = new _MyClass();
}

Access to object of Singleton:

MyClass.instance

Another option is to use Symbols in your module. This way you can protect your class, also if the final user of your API is using normal Javascript:

let _instance = Symbol();
export default class Singleton {

    constructor(singletonToken) {
        if (singletonToken !== _instance) {
            throw new Error("Cannot instantiate directly.");
        }
        //Init your class
    }

    static get instance() {
        return this[_instance] || (this[_instance] = new Singleton(_singleton))
    }

    public myMethod():string {
        return "foo";
    }
}

Usage:

var str:string = Singleton.instance.myFoo();

If the user is using your compiled API js file, also will get an error if he try to instantiate manually your class:

// PLAIN JAVASCRIPT: 
var instance = new Singleton(); //Error the argument singletonToken !== _instance symbol

You can use class expressions for this (as of 1.6 I believe).

var x = new (class {
    /* ... lots of singleton logic ... */
    public someMethod() { ... }
})();

or with the name if your class needs to access its type internally

var x = new (class Singleton {
    /* ... lots of singleton logic ... */
    public someMethod(): Singleton { ... }
})();

Another option is to use a local class inside of your singleton using some static members

class Singleton {

    private static _instance;
    public static get instance() {

        class InternalSingleton {
            someMethod() { }

            //more singleton logic
        }

        if(!Singleton._instance) {
            Singleton._instance = new InternalSingleton();
        }

        return <InternalSingleton>Singleton._instance;
    }
}

var x = Singleton.instance;
x.someMethod();

My solution for it:

export default class Modal {
    private static _instance : Modal = new Modal();

    constructor () {
        if (Modal._instance) 
            throw new Error("Use Modal.instance");
        Modal._instance = this;
    }

    static get instance () {
        return Modal._instance;
    }
}

I have found a new version of this that the Typescript compiler is totally okay with, and I think is better because it doesn't require calling a getInstance() method constantly.

import express, { Application } from 'express';

export class Singleton {
  // Define your props here
  private _express: Application = express();
  private static _instance: Singleton;

  constructor() {
    if (Singleton._instance) {
      return Singleton._instance;
    }

    // You don't have an instance, so continue

    // Remember, to set the _instance property
    Singleton._instance = this;
  }
}

This does come with a different drawback. If your Singleton does have any properties, then the Typescript compiler will throw a fit unless you initialize them with a value. That's why I included an _express property in my example class because unless you initialize it with a value, even if you assign it later in the constructor, Typescript will think it hasn't been defined. This could be fixed by disabling strict mode, but I prefer not to if possible. There is also another downside to this method I should point out, because the constructor is actually getting called, each time it does another instance is technically created, but not accessible. This could, in theory, cause memory leaks.


The best way I have found is:

class SingletonClass {

    private static _instance:SingletonClass = new SingletonClass();

    private _score:number = 0;

    constructor() {
        if(SingletonClass._instance){
            throw new Error("Error: Instantiation failed: Use SingletonClass.getInstance() instead of new.");
        }
        SingletonClass._instance = this;
    }

    public static getInstance():SingletonClass
    {
        return SingletonClass._instance;
    }

    public setScore(value:number):void
    {
        this._score = value;
    }

    public getScore():number
    {
        return this._score;
    }

    public addPoints(value:number):void
    {
        this._score += value;
    }

    public removePoints(value:number):void
    {
        this._score -= value;
    }

}

Here is how you use it:

var scoreManager = SingletonClass.getInstance();
scoreManager.setScore(10);
scoreManager.addPoints(1);
scoreManager.removePoints(2);
console.log( scoreManager.getScore() );

https://codebelt.github.io/blog/typescript/typescript-singleton-pattern/


Since TS 2.0, we have the ability to define visibility modifiers on constructors, so now we can do singletons in TypeScript just like we are used to from other languages.

Example given:

class MyClass
{
    private static _instance: MyClass;

    private constructor()
    {
        //...
    }

    public static get Instance()
    {
        // Do you need arguments? Make it a regular static method instead.
        return this._instance || (this._instance = new this());
    }
}

const myClassInstance = MyClass.Instance;

Thank you @Drenai for pointing out that if you write code using the raw compiled javascript you will not have protection against multiple instantiation, as the constraints of TS disappears and the constructor won't be hidden.


This is a typescript decorator checking if multiple instances were accidentaly created against a service class that is designed to be singleton:

https://www.npmjs.com/package/singleton-checker


namespace MySingleton {
  interface IMySingleton {
      doSomething(): void;
  }
  class MySingleton implements IMySingleton {
      private usePrivate() { }
      doSomething() {
          this.usePrivate();
      }
  }
  export var Instance: IMySingleton = new MySingleton();
}

This way we can apply an interface, unlike in Ryan Cavanaugh's accepted answer.


After implementing a classic pattern like

class Singleton {
  private instance: Singleton;
  
  private constructor() {}

  public getInstance() {
    if (!this.instance) { 
      this.instance = new Singleton();
    }
    return this.instance;
  }
}

I realized it's pretty useless in case you want some other class to be a singleton too. It's not extendable. You have to write that singleton stuff for every class you want to be a singleton.

Decorators for the rescue.

@singleton
class MyClassThatIsSingletonToo {}

You can write decorator by yourself or take some from npm. I found this proxy-based implementation from @keenondrums/singleton package neat enough.