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

new*_*cpp 15 decorator typescript

如何实现打字稿装饰器?关于如何在打字稿中使用装饰器是一个很好的例子.

考虑到以下情况,

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;
    };
}
Run Code Online (Sandbox Code Playgroud)

我尝试了一切,但似乎我无法startDateString进入装饰器参数.startDateString可以是变量,函数和引用.

Dav*_*ret 10

你想要做的是不可能的.

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

例如,使用此代码:

class MyClass {
    startDateString: string;
    @property({ afterDate: this.startDateString })
    endDateString: string;
}
let myClass = new MyClass();
Run Code Online (Sandbox Code Playgroud)
  1. MyClass 被宣布.
  2. 装饰器运行MyClass.此时不存在要传入的实例,并且this在decorator参数中引用的是全局对象 - 而不是实例.
  3. new MyClass()被调用并创建实例.此步骤不会调用装饰器.那已经发生了.

看看编译的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();
Run Code Online (Sandbox Code Playgroud)

请注意,使用this.startDateString不会抛出编译错误,因为this键入为any.

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

你可以做的是让startDateString静态的,然后通过它像这样:@property({ afterDate: MyClass.startDateString }).