30 lines
960 B
TypeScript
30 lines
960 B
TypeScript
/**
|
|
* 单例化一个class
|
|
* 使用方法:
|
|
* @singleton
|
|
* class Test {}
|
|
* new Test() === new Test() // returns `true`
|
|
* 也可以不使用 decorator
|
|
* const TestSingleton = singleton(Test)
|
|
* new TestSingleton() === new TestSingleton() //returns 'true'
|
|
*/
|
|
|
|
export const SINGLETON_KEY = Symbol()
|
|
|
|
export type Singleton<T extends new (...args: any[]) => any> = T & {
|
|
[SINGLETON_KEY]: T extends new (...args: any[]) => infer I ? I : never
|
|
}
|
|
export const singleton = <T extends new (...args: any[]) => any>(classTarget: T) =>
|
|
new Proxy(classTarget, {
|
|
construct(target: Singleton<T>, argumentsList, newTarget) {
|
|
// Skip proxy for children
|
|
if (target.prototype !== newTarget.prototype) {
|
|
return Reflect.construct(target, argumentsList, newTarget)
|
|
}
|
|
if (!target[SINGLETON_KEY]) {
|
|
target[SINGLETON_KEY] = Reflect.construct(target, argumentsList, newTarget)
|
|
}
|
|
return target[SINGLETON_KEY]
|
|
},
|
|
})
|