

let instanceMap = new Map();

export interface PrototypeType<T> extends Function
{
    prototype: T;
}

export interface ConstructorFunctionType<T = any> extends PrototypeType<T>
{
    new(...args: any[]): T;
}

export type ConstructorType<T = unknown, Static extends Record<string, any> = PrototypeType<T>> = (ConstructorFunctionType<T> | PrototypeType<T>) & {
    [Key in keyof Static]: Static[Key];
};

/**
 * 构造单例类的静态类.
 * # Example:
 *     class A extends Singleton(){};
 *     //获得单例
 *     let a = A.GetInstance();
 */
export class Singleton
{
    protected constructor() { }

    //ref:https://github.com/Microsoft/TypeScript/issues/5863
    static GetInstance<T extends Singleton>(this: ConstructorType<T, typeof Singleton>): T
    {
        if (instanceMap.has(this))
            return instanceMap.get(this);
        //@ts-ignore
        let __instance__ = new this.prototype.constructor();
        instanceMap.set(this, __instance__);
        return __instance__;
    }
}
