【问题标题】:TypeScript property decorator : access to other propertiesTypeScript 属性装饰器:访问其他属性
【发布时间】:2018-01-17 11:30:50
【问题描述】:

我有一个像这样的班级点:

class Point {
    @test('admin') x: number = 6

    y: number = 5
}

使用测试装饰器:

function test(myValue: string) {
    function t(target: Object, propertyKey: string, descriptor: 
    TypedPropertyDescriptor<any>) {
        //want to test y value > x value 
    }
return <any>t
}

在我的测试中,我想检查 y 值,例如如果 x 则抛出错误

有可能吗?

【问题讨论】:

    标签: typescript object properties decorator


    【解决方案1】:

    您的问题类似于this one

    装饰器方法中没有特定对象实例的上下文。参数如下(来自https://www.typescriptlang.org/docs/handbook/decorators.html):

    要么是静态成员的类的构造函数,要么是实例成员的类的原型

    成员的名字。

    成员的属性描述符。

    【讨论】:

    • 仅供参考,您的this one 链接指的是对答案的编辑。
    • 嘿,谢谢 :) 不知道这是怎么回事,这是一个很老的答案
    【解决方案2】:

    不,根据Typescript documentation,在对象初始化期间按以下顺序评估和调用装饰器:

    1. 参数装饰器,后跟方法、访问器或属性装饰器应用于每个实例成员。 2. 参数装饰器,然后是方法、访问器或属性装饰器应用于每个静态成员。 3. 参数装饰器应用于构造函数。 4. 类装饰器应用于类。

    他们链接到的"complete guide" 还详细说明了它如何与整个对象的初始化相关联。简而言之,在调用@test('admin') 时,尚未调用对象的构造函数(以及通过关联您对y = 3 的内联赋值)。我已经在本地测试并确认了这一点。

    【讨论】:

      【解决方案3】:

      您不能直接从装饰器函数中执行此操作。但是,您可以使用装饰器函数重新定义属性的 getter 和 setter,并访问从那里传递给它们的上下文对象:

      class Point {
          @test() x: number;
      
          y: number;
          
          constructor(x: any, y: any) {
            this.y = y; // Doing this first since the test is on the x setter
            this.x = x;
          }
      }
      
      function test() {
        function t(target: Object, propertyKey: string) {
          //want to test y value > x value 
          Object.defineProperty(target, propertyKey, {
            set: function(this, newVal) {
              if (this.y > newVal)
                this._x = newVal;
              else
                throw new Error(`${this.y} is not greater than ${newVal}!`);
            },
            get: function() {
              return this._x;
            }
          });
        };
        return t;
      }
      
      try {
        let a = new Point(1, 2);
        console.log(`a = ${a.x}`);
      }
      catch (ex) {
        console.log(ex);
      }
      
      try {
        let b = new Point(3, 2);
        console.log(`b = ${b.x}`);
      }
      catch (ex) {
        console.log(ex);
      }
      

      TypescriptLang Snippet

      【讨论】:

        猜你喜欢
        • 2019-07-29
        • 2015-08-23
        • 2018-11-26
        • 2020-06-20
        • 2019-08-21
        • 1970-01-01
        • 2018-07-20
        • 2021-06-25
        • 2016-04-29
        相关资源
        最近更新 更多