打字稿装饰设定函数

时间:2016-01-20 09:24:25

标签: typescript decorator

我试图装饰一个像这样的类的setter函数:

export class SearchResultSortBy{
    private sortByChoice;
    constructor() { ...} 

     /* getters & setters */
    get sortBy() {
        return this.sortByChoice;
    };

    @myDeco({o:'something',o2:'another something'})
    set sortBy(sortBy) {
        this.sortByChoice = sortBy;
    };

 }

与装饰者:

export function myDeco(element:any){
        return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
            descriptor.set = function(...args: any[]) {
                console.log("The method args are: " + JSON.stringify(args)); // pre
                var result = originalMethod.apply(this, args);               // run and store the result
                someOtherStaticClass.someFunc(element);               // post
                return result;                                               // return the result of the original method
            };
        return descriptor;
   };
}

但是装饰者从未被调用/没有做任何事情 如果我将@myDeco放在getter函数之上,那么装饰器就会被调用并完成它的工作,这很奇怪...(装饰setter函数。)

是否可以在typescript中装饰一个setter函数?

1 个答案:

答案 0 :(得分:3)

如果要更改位置getter和setter以使setter先行 - 将调用装饰器。

@myDeco({o:'something',o2:'another something'})
set sortBy(sortBy) {
    this.sortByChoice = sortBy;
};

get sortBy() {
    return this.sortByChoice;
};

因为你只能装饰setter或getter(从不两者),所以首先要声明的是重要的。

修改

限制装饰器放置(在setter和getter上)的原因是在javascript中定义属性的方式。 你的排序&#34;排序&#34; property getter和setter不是两个独立的属性。它是一个定义了setter和getter的属性。 装饰器附加到属性,因此您只能将其附加到属性一次。你将用来应用装饰器的getter或setter并不重要 - 结果js将完全相同。 通过查看生成的样本的js代码(稍微简化),您可以更清楚地看到我的意思:

function myDeco(element) {
    return function (target, propertyKey, descriptor) {
        descriptor.set = function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i - 0] = arguments[_i];
            }
            return 12; 
        };
        return descriptor;
    };
}
var SearchResultSortBy = (function () {
    function SearchResultSortBy() {
    }
    Object.defineProperty(SearchResultSortBy.prototype, "sortBy", {
        get: function () {
            return this.sortByChoice;
        },
        set: function (sortBy) {
            this.sortByChoice = sortBy;
        },
        enumerable: true,
        configurable: true
    });
    ;
    ;
    __decorate([
        myDeco({ o: 'something', o2: 'another something' }), 
        __metadata('design:type', Object), 
        __metadata('design:paramtypes', [Object])
    ], SearchResultSortBy.prototype, "sortBy", null);
    return SearchResultSortBy;
})();

注意如何调用__decorate函数以及它接受什么作为输入。

typescript编译器仅考虑首先定义的内容(没有装饰器的getter)并忽略应用于兄弟setter的任何装饰器这一事实 - 看起来像编译器错误,希望在将来的版本中解决。如果有更多知识的人可以证明我错了,我会很高兴这种行为是有道理的。