How do I check if 'key' is correctly populated with 'known' values in JSON file

后端 未结 3 1956
Happy的楠姐
Happy的楠姐 2021-01-23 01:49

I am trying to check if a particular key is assigned with only a set of values. This values are listed as an enum in Typescript.

P

相关标签:
3条回答
  • 2021-01-23 02:06

    If I understand correctly, you want to validate some JSON data as if it were Typescript and check if the values therein match the interfaces you provide. In general, this is impossible without using Typescript itself, luckily TS provides the compiler API which we can use in our own programs. Here's the minimal example:

    Let myjson.ts (which describes your types) be:

    type Name = 'a' | 'b' | 'c';
    
    export default interface MyJson {
        names: Name[]
        values: number[]
    }
    

    Then you can write something like:

    import * as ts from "typescript";
    import * as fs from 'fs';
    
    function compile(fileNames: string[], options: ts.CompilerOptions): string[] {
        let program = ts.createProgram(fileNames, options);
        let emitResult = program.emit();
    
        return ts
            .getPreEmitDiagnostics(program)
            .concat(emitResult.diagnostics)
            .map(d => ts.flattenDiagnosticMessageText(d.messageText, ' '));
    }
    
    function validate(someJson: string): boolean {
        let source = `
            import MyJson from "./myjson";
            let x: MyJson = ${someJson};
        `;
        fs.writeFileSync('tmp.ts', source, 'UTF-8');
        let errors = compile(['tmp.ts', 'myjson.ts'], {});
        if (errors.length)
            console.log(errors.join('\n'));
        return errors.length === 0;
    
    }
    
    ///
    
    let goodJson = '{ "names": ["a", "b"], "values": [1,2,3] }';
    let badJson  = '{ "names": ["a", "b", "x"], "values": "blah" }';
    
    console.log('ok', validate(goodJson));
    console.log('ok', validate(badJson));
    

    The result will be

    ok true
    Type '"x"' is not assignable to type 'Name'.
    Type 'string' is not assignable to type 'number[]'.
    ok false
    
    0 讨论(0)
  • 2021-01-23 02:11

    Do something like this:

    function isValidRegion(candidate: any): candidate is Regions {
          return Object.keys(Regions).some(region => region === candidate)
    }
    
    0 讨论(0)
  • 2021-01-23 02:19

    I achieved this with the following code:

    enum Regions {
    NA = "na",
    EMEA = "emea",
    APAC = "apac"
    }
    
    const possibleRegions = [Regions.NA, Regions.EMEA, Regions.APAC];
    
    private isValidRegion(value) 
    {
        return value !== null && value.Region !== null && possibleRegions.indexOf(value.Region) > -1;
    }
    
    0 讨论(0)
提交回复
热议问题