export function Singleton(preventDuplicateNew = false) { return function Singleton(cls: T): T&SingletonOf { const singleton = Symbol('@@singleton/' + cls.name); Object.defineProperty(cls, 'singleton', { get() { return this[singleton]; }, configurable: true, enumerable: false, }); return new Proxy(cls, { construct(target: T, argArray: any, newTarget?: any) { if (cls.hasOwnProperty(singleton)) { if (preventDuplicateNew) { throw new TypeError('Cannot create multiple instance of singleton class `' + cls.name + '`.'); } return cls[singleton]; } return cls[singleton] = new target(...argArray); }, }); } } /* public get singleton(): ReduxStoreWindow { return ReduxStoreWindow._singleton; } */ export interface SingletonOf { readonly singleton: T; } if (typeof Proxy === 'undefined') { // IE module.exports.Singleton = (preventDuplicateNew = false) => { return (cls: T): T => { Object.defineProperty(cls, 'singleton', { get() { return this['_singleton']; }, configurable: true, enumerable: false, }); const ret: any = function (...argArray: any[]) { if (cls.hasOwnProperty('_singleton')) { if (preventDuplicateNew) { throw new TypeError('Cannot create multiple instance of singleton class `' + cls['name'] + '`.'); } return cls['_singleton']; } return cls['_singleton'] = new (cls)(...argArray); }; Object.defineProperty(ret, 'singleton', { get() { return cls['_singleton']; }, configurable: true, enumerable: false, }); return ret; }; }; }