一个人如何实现替换访问者的打字稿属性描述符,同时维护合成性?
打字稿手册"装饰师"一章似乎意味着它不能做到,或者至少是一个坏主意。它说...
...当前没有机制来描述实例属性在定义原型的成员时,也无法观察或修改属性的初始化器。因此,只能使用属性装饰器来观察一类特定名称的属性。
但是,我发现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
我完全不确定这是正确的方法。我很想收到评论。