![](/img/trans.png)
[英]JavaScript parameter value 'becomes' undefined when passed to constructor
[英]typescript class to throw error when undefined is passed as a parameter to constructor
我有一个 class 有很多参数,简化版如下所示:
class data {
ID: string;
desp: string;
constructor(con_ID:string,con_desp:string){
this.ID = con_ID;
this.desp = con_desp;
}
}
然后我从 RESTful 调用接收数据,调用的主体是 JSON。它可能没有创建data
实例所需的所有参数。 下面是desp
未被传递的示例。
const a = JSON.stringify({ ID: 'bob' });
const b = JSON.parse(a)
如果我尝试创建一个新的数据实例,它就可以工作。
console.log(new data(b['ID'], b['desp']))
>> data { ID: undefined, desp: 'bob' }
如果来自 JSON 的参数undefined
,如何拒绝构建 class?
一种方法是对构造函数中的每个参数执行此操作,但我认为这不是正确的解决方案:
if (con_ID== undefined){
throw new Error('con_ID is undefined')
}
为此,我们可以使用 class 装饰器。 如果我们从装饰器返回 class,那么类的构造函数将替换代码中定义的构造函数。 然后我们使用参数装饰器将我们希望检查的每个参数的索引存储到一个数组中。
const noUndefinedKey = Symbol("noUndefinedKey");
const NoUndefined: ParameterDecorator = function (target, key, index) {
const data = Reflect.getMetadata(noUndefinedKey, target) ?? [];
data.push(index);
Reflect.defineMetadata(noUndefinedKey, data, target);
};
const Validate = function (target: { new (...args: any[]): any }) {
const data = Reflect.getMetadata(noUndefinedKey, target);
return class extends target {
constructor(...args: any[]) {
data.forEach((index: number) => {
if (typeof args[index] === "undefined") throw new TypeError(`Cannot be undefined.`);
});
super(...args);
}
}
}
请注意,必须使用reflect-metadata
才能使用Reflect.getMetadata
和Reflect.defineMetadata
。 以下是您将如何使用它:
@Validate
class ProtectedFromUndefined {
constructor(@NoUndefined param: string) {}
}
并尝试一些事情:
//@ts-ignore throws error because undefined was provided
new ProtectedFromUndefined()
//@ts-ignore
new ProtectedFromUndefined(undefined)
// is ok
new ProtectedFromUndefined("")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.