我想在TypeScript中创建一个装饰器,以便能够使类属性不可枚举。
我在这里找到了一个@enumerable的例子: https://www.typescriptlang.org/docs/handbook/decorators.html#method-decorators 但这似乎只适用于方法,而不是属性:
https://www.typescriptlang.org/docs/handbook/decorators.html#property-decorators
注意不提供属性描述符作为参数 由于如何初始化属性装饰器,属性装饰器 打字稿。这是因为目前没有机制 在定义原型的成员时描述实例属性, 并且无法观察或修改属性的初始化程序。如 这样,属性装饰器只能用于观察属性 已为一个类声明了特定名称。
有没有办法为类属性创建一个@enumerable装饰器?
由于
答案 0 :(得分:10)
我最终得到了这个解决方案:
/**
* @enumerable decorator that sets the enumerable property of a class field to false.
* @param value true|false
*/
function enumerable(value: boolean) {
return function (target: any, propertyKey: string) {
let descriptor = Object.getOwnPropertyDescriptor(target, propertyKey) || {};
if (descriptor.enumerable != value) {
descriptor.enumerable = value;
Object.defineProperty(target, propertyKey, descriptor)
}
};
}
用法:
class User {
id:string;
@enumerable(false)
name: string;
}
测试:
var user = new User();
user.id = 1;
user.name = 'John Doe';
for (key in user){ console.log(key, user[key]);}
输出
id 1
不使用装饰器的相同测试
id 1
name John Doe
答案 1 :(得分:2)
该解决方案实际上不起作用,或者不适用于现代打字稿。但是,以下内容可以做到:
const enumerable: {
(target: any, name: string): void;
(target: any, name: string, desc: PropertyDescriptor): PropertyDescriptor;
} = (target: any, name: string, desc?: any) => {
if(desc) {
desc.enumerable = true;
return desc;
}
Object.defineProperty(target, name, {
set(value) {
Object.defineProperty(this, name, {
value, enumerable: true, writable: true, configurable: true,
});
},
enumerable: true,
configurable: true,
});
};
const nonenumerable: {
(target: any, name: string): void;
(target: any, name: string, desc: PropertyDescriptor): PropertyDescriptor;
} = (target: any, name: string, desc?: any) => {
if(desc) {
desc.enumerable = false;
return desc;
}
Object.defineProperty(target, name, {
set(value) {
Object.defineProperty(this, name, {
value, writable: true, configurable: true,
});
},
configurable: true,
});
};