2017-11-09 2 views
2

'h.collection'에 대한 내 기대치는 [[ 'a', alpha], [ 'b', beta]], 이고 'w.collection'의 경우 [[ 'a' , 알파], [ 'c', gama]].파생 클래스의 Typescript 메서드 데코레이터

그러나 Greeter, Hello 및 World는 모두 동일한 '컬렉션'을 공유합니다. 맞습니까?

그래서 코드를 변경하려면 어떻게해야합니까?

function alias(alias: string) { 
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { 
     let func = target[propertyKey]; 
     func.alias = alias; 
     if (!target.collection) { 
      target.collection = new Map(); 
     } 
     target.collection.set(alias, func); 
    }; 
} 

abstract class Greeter { 
    public collection: Map<string, Function>; 
    @alias('a') 
    alpha(){} 
} 

class Hello extends Greeter { 
    @alias('b') 
    beta(){} 
} 

class World extends Greeter { 
    @alias('c') 
    gama(){} 
} 

let h = new Hello(); 
let w = new World(); 

console.log(h.collection); 
console.log(w.collection); 
+0

이고 tsc 대상은 "es6"입니다. – nsnze

답변

0

여기에 대한 내 어색한 해결 방법입니다. 이것은 제가 할 수있는 가장 우아한 방법입니다.

function alias(alias: string) { 
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { 
     let className: string = target.constructor.name; 
     let func = descriptor.value; 
     func.alias = alias; 

     target.shadowCollections = target.shadowCollections || {} 
     let shadowCollections = target.shadowCollections; 

     shadowCollections[className] = shadowCollections[className] || new Map(); 
     let collection: Map<string, Function> = shadowCollections[className]; 

     collection.set(alias, func); 
    }; 
} 

function fix<T extends { new(...args: any[]): {} }>(ctor: T) { 
    let all: [string, Function][] = []; 
    function* getClassNames(_ctor: T) { 
     while (_ctor && _ctor.name) { 
      yield _ctor.name; 
      _ctor = Object.getPrototypeOf(_ctor); 
     } 
    } 
    for (let className of getClassNames(ctor)) { 
     let current: Map<string, Function> = ctor.prototype.shadowCollections[className]; 
     all.push(...current); 
    } 
    all.sort(([a,], [b,]) => a < b ? -1 : (a > b ? 1 : 0)); 
    delete ctor.prototype.shadowCollections; 
    return class extends ctor { 
     _collection = new Map(all); 
    } 
} 

abstract class Greeter { 
    protected _collection: Map<string, Function>; 
    public get collection(): Map<string, Function> { 
     return this._collection; 
    } 
    @alias('a') 
    alpha() { } 
} 

@fix 
class Hello extends Greeter { 
    @alias('b') 
    beta() { } 
} 

@fix 
class World extends Greeter { 
    @alias('c') 
    gama() { } 
} 

let h = new Hello(); 
let w = new World(); 

console.log(h.collection); 
console.log(w.collection); 
관련 문제