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

孤者浪人 提交于 2019-12-04 04:47:51

问题


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.

Please note, I do that want to check the values directly like it explained below, but would like to check the enum type.

Check if key/value is in JSON

I need to check only known regions are used in the json file.

export type Regions = Na | Emea | Apac;

export interface Na {
    NA: "na";
}

export interface Emea {
    EMEA: "emea";
}

export interface Apac {
    APAC: "apac";
}

I need to write a function similar to below which check of only known values are used for the key Region

function isValidRegion(candidate: any): candidate is Regions {
 // if (candidate is one the type of Regions
 // console.log("Regions valid");
 // else
 // console.log("invalid Regions are used in input JSON");
 result = candidate;
 return result;
}

回答1:


Do something like this:

function isValidRegion(candidate: any): candidate is Regions {
      return Object.keys(Regions).some(region => region === candidate)
}



回答2:


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



回答3:


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


来源:https://stackoverflow.com/questions/57942107/how-do-i-check-if-key-is-correctly-populated-with-known-values-in-json-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!