如何将实例变量传递给typescript decorator参数?

时间:2016-01-13 00:20:05

标签: typescript decorator

How to implement a typescript decorator?是关于如何在打字稿中使用装饰器的一个很好的例子。

考虑以下情况,

class MyClass {
    @enumerable(false)
    get prop() {
        return true;
    }

    @property({required: true}) //here pass constant is no issue
    public startDateString:string;

    @property({afterDate: this.startDateString}) //how to pass startDateString here?
    public endDateString:string;
}

function enumerable(isEnumerable: boolean) {
    return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
        descriptor.enumerable = isEnumerable;
        return descriptor;
    };
}

我尝试了一切,但似乎我无法将startDateString传递给装饰器参数。 startDateString可以是变量,函数和引用。

2 个答案:

答案 0 :(得分:10)

你想要做的事情是不可能的。

在声明类时调用装饰器,此时没有实例传递给装饰器。

例如,使用以下代码:

class MyClass {
    startDateString: string;
    @property({ afterDate: this.startDateString })
    endDateString: string;
}
let myClass = new MyClass();
    宣布
  1. MyClass
  2. 装饰器在MyClass上运行。此时不存在要传入的实例,并且装饰器参数中的this引用全局对象 - 而不是实例。
  3. 调用
  4. new MyClass()并创建实例。装饰者不会在此步骤中被调用。那已经发生了。
  5. 查看已编译的JavaScript以供参考:

    var MyClass = (function () {
        // -- 1 --
        function MyClass() {
        }
        // -- 2 --
        __decorate([
            // see here... `this` is equal to the global object
            property({ afterDate: this.startDateString })
        ], MyClass.prototype, "endDateString", void 0);
        return MyClass;
    })();
    // -- 3 --
    var myClass = new MyClass();
    

    请注意,使用this.startDateString不会在此处抛出编译错误,因为this的类型为any

    那么通过传入一个实例属性试图在这里做的事情是没有意义的,也是不可能的。

    您可以做的是将startDateString设为静态,然后将其传递出去:@property({ afterDate: MyClass.startDateString })

答案 1 :(得分:3)

您无法从属性定义访问对象属性。

定义属性时会调用Decorator。

您可以在访问该属性时使用getter或setter来获取控制权。