When deciding whether to allow the creation of a new instance for a singleton class, one must consider various factors. In some cases, the getInstance
method can be excluded and the class constructor itself can function as a singleton factory:
class Foo {
private static _instance;
constructor(...args) {
if (Foo._instance) {
return Foo._instance;
}
// perform additional operations here if needed
Foo._instance = this;
};
}
A similar approach can also be applied using decorators for different classes, such as:
@singleton
class Foo { ... }
However, due to certain typing issues with TypeScript decorators as described here, it is recommended to implement custom inheritance logic within the singleton
decorator instead of relying on Singleton extends Class
:
function singleton(Class) {
function extend(sub, sup) {
for (var prop in sup)
if (sup.hasOwnProperty(prop))
sub[prop] = sup[prop];
function __() {
this.constructor = sub;
}
__.prototype = sup.prototype;
sub.prototype = new __();
};
const Singleton = <any>function (...args) {
if (Singleton._instance) {
return Singleton._instance;
}
Class.apply(this, args);
Singleton._instance = this;
}
extend(Singleton, Class);
return Singleton;
}
Although this approach may impact typing, it helps maintain a clean syntax.