javascript - Hur kontrollerar jag om 'key' är korrekt ifylld med 'known'-värden i JSON-fil


Jag försöker kontrollera om en viss key är tilldelad endast en uppsättning values. Dessa värden listas som en enum i Typescript.

Observera, jag vill inte kontrollera values direkt som det förklaras nedan, men vill kontrollera enum-typen.

Kontrollera om nyckel/värde finns i JSON

Jag behöver kontrollera att endast kända regioner används i json-filen.

export type Regions = Na | Emea | Apac;

export interface Na {
    NA: "na";
}

export interface Emea {
    EMEA: "emea";
}

export interface Apac {
    APAC: "apac";
}

Jag behöver skriva en funktion liknande nedan som kontrollerar att endast kända värden används för nyckeln 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;
}

Svar #1

Om jag förstår rätt vill du validera viss JSON-data som om det vore Typescript och kontrollera om värdena där matchar de gränssnitt du tillhandahåller. Generellt är detta omöjligt utan att använda Typescript själv, men som tur är tillhandahåller TS compiler-API:t som vi kan använda i våra egna program. Här är det minimala exemplet:

Låt myjson.ts (som beskriver dina typer) vara:

type Name = 'a' | 'b' | 'c';

export default interface MyJson {
    names: Name[]
    values: number[]
}

Då kan du skriva något som:

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

Resultatet kommer att bli

ok true
Type '"x"' is not assignable to type 'Name'.
Type 'string' is not assignable to type 'number[]'.
ok false

Svar #2

Gör något liknande detta:

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

Relaterade artiklar