我想写一个消毒剂装饰器,我可以把它放在所有用户输入的字符串字段上。这只是将标准替换.set(newValue)
为.set( sanitize(newValue) )
. 但是我发现下面的代码只适用于一个实例。同一类的第二个实例最终共享 currentValue。在进一步阅读之后,这实际上是预期的,但我无法弄清楚如何在每个实例中制作它。
import "reflect-metadata";
export const Sanitize = () => {
return (target: any, propertyKey: string | symbol) => {
let currentValue: any = sanitiseString(options, `${target[propertyKey] || ''}`);
Reflect.deleteProperty(target, propertyKey);
Reflect.defineProperty(target, propertyKey, {
get: () => currentValue,
set: (newValue: string) => {
currentValue = sanitiseString(newValue);
},
});
}
}
编辑 1:最小可重现示例:
import "reflect-metadata";
const sanitiseString = (valToSanitise: string) => {
// do some stuff, return clean value
return valToSanitise;
}
const Sanitize = () => {
return (target: any, propertyKey: string | symbol) => {
let currentValue: any = sanitiseString(`${target[propertyKey] || ''}`);
Reflect.deleteProperty(target, propertyKey);
Reflect.defineProperty(target, propertyKey, {
get: () => currentValue,
set: (newValue: string) => {
currentValue = sanitiseString(newValue);
},
});
}
}
class UserInput {
constructor(propOne: string, propTwo: string, propThree: number) {
this.propOne = propOne;
this.propTwo = propTwo;
this.propThree = propThree;
}
@Sanitize() propOne: string
@Sanitize() propTwo: string
propThree: number
}
const inputOne = new UserInput('input 1, prop 1', 'input 1, prop 2', 1)
const inputTwo = new UserInput('input 2, prop 1', 'input 2, prop 2', 2)
console.log(inputOne)
console.log(inputTwo)
// expected output:
// [LOG]: UserInput: {
// "propOne": "input 1, prop 1",
// "propTwo": "input 1, prop 2",
// "propThree": 1
// }
// [LOG]: UserInput: {
// "propOne": "input 2, prop 1",
// "propTwo": "input 2, prop 2",
// "propThree": 2
// }
//
// actual output:
//
// [LOG]: UserInput: {
// "propThree": 1
// }
// [LOG]: UserInput: {
// "propThree": 2
// }
// When you remove @Sanitize() the fields appear in console.log. When you add @Sanitize() the fields disappear.
// Further, forcing console.log(inputOne.propOne) returns [LOG]: "input 2, prop 1"
// indicating that the property is being written for the class proto and not per instance
console.log(inputOne.propOne)