如何检查 'key' 是否正确填充了 JSON 文件中的 'known' 值
How do I check if 'key' is correctly populated with 'known' values in JSON file
我正在尝试检查某个 key
是否仅分配了一组 values
。此值在 Typescript 中列为 enum
。
请注意,我这样做是想像下面解释的那样直接检查 values
,但想检查 enum
类型。
我只需要检查 json
文件中使用的已知区域。
export type Regions = Na | Emea | Apac;
export interface Na {
NA: "na";
}
export interface Emea {
EMEA: "emea";
}
export interface Apac {
APAC: "apac";
}
我需要编写一个类似于下面的函数,它只检查已知值用于键 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;
}
做这样的事情:
function isValidRegion(candidate: any): candidate is Regions {
return Object.keys(Regions).some(region => region === candidate)
}
如果我没理解错的话,你想像验证 Typescript 一样验证一些 JSON 数据,并检查其中的值是否与你提供的接口匹配。一般来说,如果不使用 Typescript 本身这是不可能的,幸运的是 TS 提供了 compiler API 我们可以在我们自己的程序中使用。这是最小的例子:
令 myjson.ts
(描述您的类型)为:
type Name = 'a' | 'b' | 'c';
export default interface MyJson {
names: Name[]
values: number[]
}
然后你可以这样写:
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));
结果将是
ok true
Type '"x"' is not assignable to type 'Name'.
Type 'string' is not assignable to type 'number[]'.
ok false
我用下面的代码实现了这个:
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;
}
我正在尝试检查某个 key
是否仅分配了一组 values
。此值在 Typescript 中列为 enum
。
请注意,我这样做是想像下面解释的那样直接检查 values
,但想检查 enum
类型。
我只需要检查 json
文件中使用的已知区域。
export type Regions = Na | Emea | Apac;
export interface Na {
NA: "na";
}
export interface Emea {
EMEA: "emea";
}
export interface Apac {
APAC: "apac";
}
我需要编写一个类似于下面的函数,它只检查已知值用于键 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;
}
做这样的事情:
function isValidRegion(candidate: any): candidate is Regions {
return Object.keys(Regions).some(region => region === candidate)
}
如果我没理解错的话,你想像验证 Typescript 一样验证一些 JSON 数据,并检查其中的值是否与你提供的接口匹配。一般来说,如果不使用 Typescript 本身这是不可能的,幸运的是 TS 提供了 compiler API 我们可以在我们自己的程序中使用。这是最小的例子:
令 myjson.ts
(描述您的类型)为:
type Name = 'a' | 'b' | 'c';
export default interface MyJson {
names: Name[]
values: number[]
}
然后你可以这样写:
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));
结果将是
ok true
Type '"x"' is not assignable to type 'Name'.
Type 'string' is not assignable to type 'number[]'.
ok false
我用下面的代码实现了这个:
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;
}