Class 编写一个TypeScript修饰符来始终将类方法绑定到';这';

Class 编写一个TypeScript修饰符来始终将类方法绑定到';这';,class,typescript,scope,decorator,abstract,Class,Typescript,Scope,Decorator,Abstract,我正试图编写一个装饰程序,以便始终将类方法的作用域绑定到该类的实例 这是我迄今为止的实施情况: function LockThis<T extends { new(...args: any[]): {} }>(constructor: T) { let self: any; const locker = class extends constructor { constructor(...args: any[]) { super(...args);

我正试图编写一个装饰程序,以便始终将类方法的作用域绑定到该类的实例

这是我迄今为止的实施情况:

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
是否有一个不同类型的保护来允许实际类和抽象类,以及/或者每个方法都有这样做的方法

(我对每个方法的尝试都是徒劳的,因为在调用该方法之前,我似乎无法确定“this”,如果使用不同的作用域调用,则为时已晚)

根据,没有很好的方法来引用抽象构造函数类型。这里提到的解决方法是只使用
函数
,这太过宽松(并非所有函数都是构造函数),但可能对您有效,因为您不太可能尝试在随机函数上使用类装饰器

而且您不能在
函数上进行混入,因此实现需要仍然认为您有一个构造函数。因此,我建议您在
锁上使用此
,以便调用者看到
函数
,但实现仍然看到它可以扩展的构造函数。例如:

// callers see a function that takes any function and returns the same type
function LockThis<T extends Function>(constructor: T): T;

// implementation is unchanged, and still sees a (concrete) constructor
function LockThis<T extends { new(...args: any[]): {} }>(constructor: T) {
  // ... your unchanged implementation here
}
这是我最接近你想要的。希望有帮助;祝你好运

class Something {
  private foo = 'bar';

  @LockThis()
  public doIt(someVar?: string) {
    return this.stuff + ' ' + someVar;
  }
}
// callers see a function that takes any function and returns the same type
function LockThis<T extends Function>(constructor: T): T;

// implementation is unchanged, and still sees a (concrete) constructor
function LockThis<T extends { new(...args: any[]): {} }>(constructor: T) {
  // ... your unchanged implementation here
}
@LockThis // no error
abstract class Blah { }