【问题标题】:typescript decorate setter function打字稿装饰设置器功能
【发布时间】:2018-11-27 15:58:46
【问题描述】:

我正在尝试装饰一个 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 函数?

【问题讨论】:

    标签: typescript decorator


    【解决方案1】:

    如果您要更改位置 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 中定义属性的方式。 您的“sortby”属性 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 的任何装饰器的事实 - 看起来像一个编译器错误,希望在未来的版本中得到解决。如果有更多知识的人可以证明我错了并且有这种行为的原因,我会很高兴。

    【讨论】:

    • 这确实有效。你能详细说明为什么订单如此重要吗?为什么我不能同时装饰两者?是打字稿成熟度问题吗?
    猜你喜欢
    • 2018-05-10
    • 2020-03-28
    • 1970-01-01
    • 2018-11-07
    • 2018-06-21
    • 2019-07-29
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多