typescript - 使用 TypeScript 属性描述符替换访问器,同时保留可组合性

标签 typescript

如何实现 TypeScript 属性描述符来替换访问器,同时保持可组合性?

最佳答案

TypeScript 手册 Decorators chapter似乎暗示这是不可能做到的,或者至少是一个坏主意。它说...

...there is currently no mechanism to describe an instance property when defining members of a prototype, and no way to observe or modify the initializer for a property. As such, a property decorator can only be used to observe that a property of a specific name has been declared for a class.

但是,我发现 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

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

关于typescript - 使用 TypeScript 属性描述符替换访问器,同时保留可组合性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42730391/

相关文章:

javascript - 如何通过 id 存储在变量中来渲染组件?

TypeScript:将 Container<Maybe<unknown>> 转换为 Maybe<Container<unknown>>

typescript - 展开 window 对象的 Typescript 定义

typescript 2.4.2 "or"类型奇怪的行为

typescript - 字符串文字类型和类型 "string"可以混合用作映射类型中的键吗?

javascript - 用 typescript 迭代 map 不起作用

typescript - 如何从 TypeScript 使用 getUserMedia

reactjs - 强类型 useDynamicCallback

javascript - 将 Nest.js 应用程序导入为简单的 Express 中间件

typescript - Typescript 接口(interface)可以表达属性的共现约束吗