我对' h.collection'的期望是[[' a',alpha],[' b',beta]], 并且对于' w.collection'是[[' a',alpha],[' c',gama]]。
但是Greeter,Hello和World都只是分享了相同的#39;对吧?
那么,我应该更改哪些代码?
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 :(得分: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);