我正在尝试在TypeScript中构建一个模型,该模型利用用作数据注释的装饰器来执行某种数据验证。基本上,使用以下cnde:
function IsString(target: any,propertyKey: string | symbol,descriptor?: PropertyDescriptor) : any {
// NOTE: This should be called each time the property is set.
}
class Person {
@IsString
name : string = '';
@IsString
surname : string = '';
constructor(name: string,surname: string) {
this.name = name;
this.surname = surname;
}
}
let foo = new Person('pippo','pluto');
foo.name = 'paperino'; // Validation should run,and be OK
foo.name = 7; // Validation should run,and somehow warn me
每次设置属性IsString
和name
时,我都想运行surname
验证。
我尝试了不同的方法,例如使用代理来拦截每个属性的set
,但是后来我不知道如何运行不同的装饰器。让我再次向您展示:
const PersonProxied = (name,surname,classGenerator: { new(name,surname): any }) => new Proxy(new classGenerator(name,surname),validator);
let validator = {
set: function(obj: any,prop: any,value: any) {
console.log(obj);
obj[prop] = value;
// NOTE → Here,I should run the decorator defined for property obj[prop].
return true;
}
}
let foo = PersonProxied('pippo','pluto',Person);
使用此配置,每次Person
属性更改时,我都设法拦截。但是,在validator
内部,我不知道如何(甚至可能)访问给定属性的装饰器。
如果我是正确的话,问题是IsString
函数只为类原型调用一次,而不是为Person
的每个实例调用一次。因此,它无法在类的实例上正确运行验证。
在这一点上,我不知道这是否可能。我的意思是,我认为是这样,因为在网上查看时,我已经找到了一些类似的库,但是我想自己实现算法,并且主要是了解算法的工作原理。
P.S。我仍然不知道如何维护每个属性的验证状态。大概我可以在Person
中有一个对象,就像这样:
class Person {
...
validatation = {
name: { hasError: true,errors: ['error1','error2'] },surname: { hasError: false }
};
...
}