简体   繁体   English

typescript class 当未定义作为参数传递给构造函数时抛出错误

[英]typescript class to throw error when undefined is passed as a parameter to constructor

I have a class with a lot of parameters, a simplified version is shown below:我有一个 class 有很多参数,简化版如下所示:

class data {

    ID: string;
    desp: string;

    constructor(con_ID:string,con_desp:string){
        this.ID = con_ID;
        this.desp = con_desp;
    }
}

I am then receiving data from a RESTful call, the body of the call is JSON. It might not have all the parameters requried to create an instance of data .然后我从 RESTful 调用接收数据,调用的主体是 JSON。它可能没有创建data实例所需的所有参数。 Below is an example of the desp not being passed.下面是desp未被传递的示例。

const a = JSON.stringify({ ID: 'bob' });
const b = JSON.parse(a)

If I try to create a new instance of data, it works.如果我尝试创建一个新的数据实例,它就可以工作。

console.log(new data(b['ID'], b['desp']))
>> data { ID: undefined, desp: 'bob' }

How do I reject the construction of the class if a parameter from JSON is undefined ?如果来自 JSON 的参数undefined ,如何拒绝构建 class?

One method would be to do this for each parameter within the constructor, but I don't think this is the correct solution:一种方法是对构造函数中的每个参数执行此操作,但我认为这不是正确的解决方案:

    if (con_ID== undefined){
        throw new Error('con_ID is undefined')
    }

We can utilize class decorators for this.为此,我们可以使用 class 装饰器。 If we return a class from the decorator then the class' constructor will replace the one defined in code.如果我们从装饰器返回 class,那么类的构造函数将替换代码中定义的构造函数。 Then we use parameter decorators to store the index of each parameter we wish to check into an array.然后我们使用参数装饰器将我们希望检查的每个参数的索引存储到一个数组中。

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);
        }
    }
}

Note that reflect-metadata must be used to use Reflect.getMetadata and Reflect.defineMetadata .请注意,必须使用reflect-metadata才能使用Reflect.getMetadataReflect.defineMetadata Here's how you would use it:以下是您将如何使用它:

@Validate
class ProtectedFromUndefined {
    constructor(@NoUndefined param: string) {}
}

And try a few things:并尝试一些事情:

//@ts-ignore throws error because undefined was provided
new ProtectedFromUndefined()
//@ts-ignore
new ProtectedFromUndefined(undefined)

// is ok
new ProtectedFromUndefined("")

Playground 操场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 传递给构造函数时,JavaScript参数值'becomes'未定义 - JavaScript parameter value 'becomes' undefined when passed to constructor angular.js:Typescript类构造函数“这是未定义的” - angular.js: Typescript class constructor “this is undefined” 为什么在键入Redux-saga调用参数时Typescript会引发错误-TS2339 - Why does Typescript throw an error when typing Redux-saga call parameter - TS2339 为什么在类构造函数中使用setState方法时React会抛出错误? - Why does React throw an error when setState method used in a class constructor? 'Uncaught TypeError: Class extends value undefined is not a constructor or null' 尝试加载外部 TypeScript 组件时 - 'Uncaught TypeError: Class extends value undefined is not a constructor or null' when trying to load external TypeScript component 当initialDueDate参数无效的javascript时引发错误 - throw an error when initialDueDate parameter is invalid javascript 关于 class 构造函数中未初始化变量的 TypeScript 错误 - TypeScript error regarding uninitialized variables in class constructor 打字稿:undefined不是构造函数 - Typescript: undefined is not a constructor 在构造函数中定义时,未定义的类变量 - Undefined class variable when defined in constructor 当没有错误时,回调应该传递 null 还是 undefined? - Should a callback be passed null or undefined when there is no error?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM