【发布时间】:2018-04-19 00:02:50
【问题描述】:
我正在尝试编写一个装饰器来始终将类方法的范围绑定到该类的实例。
这是我目前的实现:
function LockThis<T extends { new(...args: any[]): {} }>(constructor: T) {
let self: any;
const locker = class extends constructor {
constructor(...args: any[]) {
super(...args);
self = this;
}
};
const proto = constructor.prototype;
Object.getOwnPropertyNames(proto).forEach(key => {
if (key === 'constructor') {
return;
}
const descriptor = Object.getOwnPropertyDescriptor(proto, key);
if (descriptor && typeof descriptor.value === 'function') {
const original = descriptor.value;
locker.prototype[key] = (...a: any[]) => original.apply(self, a);
}
});
return locker;
}
@LockThis
class Something {
private foo = 'bar';
public doIt(someVar?: string) {
return this.foo + ' ' + someVar;
}
}
const something = new Something();
console.log(something.doIt.call({}, 'test'));
--> bar test
这有效,抽象类除外:
@LockThis
abstract class Blah {
}
TS2345: Argument of type 'typeof Blah' is not assignable to parameter of type 'new (...args: any[]) => {}'.
Cannot assign an abstract constructor type to a non-abstract constructor type.
是否有不同的类型保护可用于允许实际类和抽象类和/或替代方法来执行此操作?
(我对每个方法的尝试都是徒劳的,因为在调用方法之前我似乎无法确定“this”,如果使用不同的范围调用就太晚了)
class Something {
private foo = 'bar';
@LockThis()
public doIt(someVar?: string) {
return this.stuff + ' ' + someVar;
}
}
【问题讨论】:
标签: class typescript scope decorator abstract