打字稿:一个类方法可以成为另一个方法的装饰器吗?

时间:2019-06-21 20:14:37

标签: typescript

下面的方法可以工作吗?

class A {
  private mySecretNumber = 2;

  decorate (f: (x :number) => number) {
    return (x: number) => f(this.mySecretNumber * x);
  }

  @(this.decorate)
  method (x: number) {
    return x + 1;
  }
}

我尝试过@this['decorate'], @A['decorate']@A.decorate找不到任何东西。

这是我的用例示例:https://kutt.it/uOxVgM。理想情况下,我只装饰getAbc()get123()

2 个答案:

答案 0 :(得分:3)

您的问题有很多妙处。

第一件事是,是的,您确实可以使用方法作为修饰符,但不能通过编写@this.decorate(在编译期间,this将是globalThis而不是{{ 1}}或A@A.decorate不是静态方法,因此decorate不存在)。问题的这一部分的正确答案是A.decorate;这将完全确定您的想法。

第二件事是,当将装饰器应用于类的方法时,装饰器的参数不是方法函数本身,而是实际上具有3个参数:目标对象(应为@A.prototype.decorate在我们的例子中),一个字符串(方法的名称,在我们的例子中为A.prototype)和一个属性描述符对象。它还不返回新函数,但如果不为空,则应返回新的属性描述符。因此,在装饰器函数内部,您应该尝试修改目标对象,而不是尝试返回新函数。

将所有内容放在一起,一个有效的示例将是:

"method"

更新:

根据您的用例,我将使用以下方法。基本上,您使用静态装饰器来加载抽象的class A { private mySecretNumber = 2; decorate(target: any, propertyKey: string, descriptor: PropertyDescriptor) { var f = descriptor.value; // Don't use arrow function here, otherwise "this" // will not be the current A instance. descriptor.value = function(x: number) { return f(this.mySecretNumber * x); }; Object.defineProperty(target, propertyKey, descriptor); } @A.prototype.decorate method(x: number) { return x + 1; } } var a = new A(); console.log(a.method(3)); // 7 方法,该方法可以在子类中实现。我修改了上面的示例,以使您了解如何完成此操作。

decorate

答案 1 :(得分:0)

您可以通过使用类型约束来实现装饰器,以将其适用范围限制为实现mySecretNumber属性的类。这样可以修复蔡慕尊explained so well的范围界定问题的语法和语义。

这就是我想要的:

class A {
    mySecretNumber = 2;
    @decorate
    method(x: number) {
        return x + 1;
    }
}

function decorate<T extends { mySecretNumber: number }, K extends keyof T>(
    target: T, key: K,
    descriptor: T[K] extends (n: number) => number ? TypedPropertyDescriptor<(n: number) => number> : never
) {
    const f = descriptor.value;
    if (f) {
        descriptor.value = function (this: T, x: number) {
            return f(this.mySecretNumber * x);
        };
    }
    return descriptor;
}

这可确保修饰的类具有类型mySecretNumber的{​​{1}}属性,将该成员绑定到所需的number,此外,还要确保修饰的方法具有正确的签名

相关问题