All files / src/classes/decorators Singleton.ts

100% Statements 9/9
100% Branches 1/1
100% Functions 2/2
100% Lines 9/9

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 542x                                                   2x     1x               1x     8x 1x     8x       1x     1x    
import { copyStaticProperties } from './Helper';
 
/**
 * Singleton decorator.
 * @param constructor The constructor to create a singleton from.
 * @param args Other arguments from the decorator interface.
 * @returns The singleton class.
 * @remarks - To get the singleton instance, call the constructor.
 * - Place this decorator directly above the class declaration
 * @example
 * ```ts
 * \@anotherDecorators //---> third priority
 * \@otherDecorators   //--> second priority
 * \@Singleton         //-> first priority
 * class MyClass {     // Place the Singleton decorator
 *    constructor() {  // directly above the class declaration
 *       // ...        // for priority above other decorators!
 *   }
 * }
 *
 * const instance = new MyClass();
 * const instance2 = new MyClass();
 *
 * console.log(instance === instance2); // true
 * ```
 */
export function Singleton<
    TargetType extends new (...args: unknown[]) => InstanceType<TargetType>,
>(constructor: TargetType, ...args: unknown[]): TargetType {
    const original = constructor;
    let instance: InstanceType<TargetType>;
 
    /**
     * Wraps the constructor to create a singleton.
     * @param args The arguments for the constructor.
     * @returns The singleton instance.
     */
    const wrappedConstructor = function (
        ...args: unknown[]
    ): InstanceType<TargetType> {
        if (!instance) {
            instance = new constructor(...args) as InstanceType<TargetType>;
        }
 
        return instance;
    };
 
    // Transfer prototype
    wrappedConstructor.prototype = constructor.prototype;
 
    // Copy static methods and properties
    return copyStaticProperties(wrappedConstructor, original);
}
 
Zur TypeDoc-Dokumentation