使用TypeScript属性描述符来替换登录器,同时保持合并性



一个人如何实现替换访问者的打字稿属性描述符,同时维护合成性?

打字稿手册"装饰师"一章似乎意味着它不能做到,或者至少是一个坏主意。它说...

...当前没有机制来描述实例属性在定义原型的成员时,也无法观察或修改属性的初始化器。因此,只能使用属性装饰器来观察一类特定名称的属性。

但是,我发现Object.getOwnPropertyDescriptor(target, key)似乎提供了所需的内容。

这是一个示例:

function decorator(name: string) {
    return function (target: any, key: string) {
        try {
            console.log(`${name}...`);
            let localValue = undefined;
            let prev = Object.getOwnPropertyDescriptor(target, key);
            let setter = function (newVal) {
                try {
                    console.log(`${name} setter(${newVal}) called...`);
                    if (prev) prev.set(newVal);
                    localValue = newVal;
                } finally {
                    console.log(`...${name} setter called`);
                }
            };
            let getter = function () {
                try {
                    console.log(`${name} getter(${localValue}) called...`);
                    if (prev) prev.get();
                    return localValue;
                } finally {
                    console.log(`...${name} getter called`);
                }
            };
            Object.defineProperty(target, key, {
                get: getter,
                set: setter,
                enumerable: prev == null ? true : prev.enumerable,
                configurable: prev == null ? true : prev.configurable
            });
        } finally {
            console.log(`...${name}`);
        }
    }
}
class MyClass {
    @decorator("decorator1")
    @decorator("decorator2")
    myProperty: string;
}
var mc = new MyClass();
mc.myProperty = "asdf";
console.log(mc.myProperty);

输出为:

decorator2...
...decorator2
decorator1...
...decorator1
decorator1 setter(asdf) called...
decorator2 setter(asdf) called...
...decorator2 setter called
...decorator1 setter called
decorator1 getter(asdf) called...
decorator2 getter(asdf) called...
...decorator2 getter called
...decorator1 getter called
asdf

我完全不确定这是正确的方法。我很想收到评论。

最新更新