npm install ajv
JSON Schema / JSON Type Definition
Ajv는 스키마를 함수로 컴파일하고 모든 경우를 캐시 합니다.
JSON Schema 예시
const Ajv = require("ajv");
const ajv = new Ajv();
const schema = {
type: "object",
properties: {
name: { type: "string" },
age: { type: "integer" },
},
required: ["name"],
additionalProperties: false,
};
// create Validation Function
const validate = ajv.compile(schema);
// Test Success Data
const successed_data = {
name: "woodong",
age: 3,
};
// Test Fail Data
const failed_data = {
name: "woodong",
age: "3",
};
const valid_1 = validate(successed_data);
const valid_2 = validate(failed_data);
// 검증
if (!valid_1) {
console.log(validate.errors);
}
if (!valid_2) {
console.log(validate.errors);
}
// 실패 Log
[
{
instancePath: '/age',
schemaPath: '#/properties/age/type',
keyword: 'type',
params: { type: 'integer' },
message: 'must be integer'
}
]
const Ajv = require("ajv/dist/jtd");
const ajv = new Ajv();
const schema = {
properties: {
name: { type: "string" },
},
optionalProperties: {
age: { type: "int32" },
},
};
const validate = ajv.compile(schema);
const data = {
name: "woodong",
age: 28,
};
const valid = validate(data);
if (!valid) console.log(validate.errors);
JSON.stringify
( JS 코드를 JSON 문자열로 변환 )보다 10배 이상 빠릅니다.JSON.parse
( JSON 문자열의 구문을 분석하고 JS 객체 형태로 변환)와 속도가 비슷합니다.JSON.parse
보다 더 빨리 실패함으로 더 효율적일 수 있습니다.JSON.parse
가 더 좋습니다.const Ajv = require("ajv/dist/jtd");
const ajv = new Ajv();
const schema = {
properties: {
name: { type: "string" },
},
optionalProperties: {
age: { type: "int32" },
},
};
// create serialize function
const serialize = ajv.compileSerializer(schema);
const data = {
name: "woodong",
age: 28,
};
// result: {"name":"woodong","age":32}
console.log(serialize(data));
// create parse function
const parse = ajv.compileParser(schema);
const json = '{"name": "woodong", "age": 28}';
const invalidJson = '{"unknown": "abc"}';
// result: { name: 'woodong', age: 28 }
console.log(parse(json));
// result: undefind => 예외 처리 제공하지 않음 ( parse 함수 자체 내장 )
console.log(parse(invalidJson));
// parseAndLog 함수 ( 따로 구현 필요 )
function parseAndLog(json) {
const data = parse(json);
if (data === undefined) {
console.log(parse.message); // error message from the last parse call
console.log(parse.position); // error position in string
} else {
console.log(data);
}
}
// property unknown not allowed
// 11
console.log(parseAndLog(invalidJson));
tsconfig.json
옵션에 strictNullChecks: true
추가해야함
strictNullChecks
: 개발자가 null
/ undefinded
값을 참조하는 것을 방지JSON Schema 예시
import Ajv, { JSONSchemaType } from "ajv";
const ajv = new Ajv();
interface userType {
name: string;
age?: number;
}
const schema: JSONSchemaType<userType> = {
type: "object",
properties: {
name: { type: "string" },
age: { type: "integer", nullable: true },
},
required: ["name"],
additionalProperties: false,
};
// create Validation Function
const validate = ajv.compile(schema);
// Test Success Data
const successed_data = {
name: "woodong",
age: 3,
};
// Test Fail Data
const failed_data = {
name: "woodong",
age: "3",
};
const valid_1 = validate(successed_data);
const valid_2 = validate(failed_data);
// 검증
if (!valid_1) {
console.log(validate.errors);
}
if (!valid_2) {
console.log(validate.errors);
}
import Ajv, { JTDSchemaType } from "ajv/dist/jtd";
const ajv = new Ajv();
interface userType {
name: string;
age?: number;
}
const schema: JTDSchemaType<userType> = {
properties: {
name: { type: "string" },
},
optionalProperties: {
age: { type: "int32" },
},
};
const validate = ajv.compile(schema);
const data = {
name: "woodong",
age: 28,
};
const valid = validate(data);
if (!valid) console.log(validate.errors);
import Ajv, { JTDDataType } from "ajv/dist/jtd";
const ajv = new Ajv();
const schema = {
properties: {
name: { type: "string" },
},
optionalProperties: {
age: { type: "int32" },
},
} as const;
type userType = JTDDataType<typeof schema>;
const validate = ajv.compile<userType>(schema)
/* 예상 Type
type userType2 = {
name: string;
age?: number;
};
*/
/* 변경된 type
type userType = {
name: string;
} & {
age?: number | undefined;
}
*/
import Ajv, { JSONSchemaType } from "ajv";
const ajv = new Ajv();
type MyUnion = { prop: boolean } | string | number;
const schema: JSONSchemaType<MyUnion> = {
anyOf: [
{
type: "object",
properties: { prop: { type: "boolean" } },
required: ["prop"],
},
{
type: ["string", "number"],
},
],
};
import Ajv, { JSONSchemaType } from "ajv";
const ajv = new Ajv();
interface userType<T> {
name: T;
age?: number;
}
const schema: JSONSchemaType<userType<string>> = {
type: "object",
properties: {
name: { type: "string" },
age: { type: "integer", nullable: true },
},
required: ["name"],
additionalProperties: false,
};
npm i json-schema-to-ts
import { FromSchema } from "json-schema-to-ts";
const schema = {
type: "object",
properties: {
name: { type: "string" },
age: { type: "integer", nullable: true },
},
required: ["name"],
additionalProperties: false,
} as const;
type userType = FromSchema<typeof schema>;
// 생성된 Type
// type userType = {
// name: string;
// age?: number | undefined;
// }
const enumSchema = {
enum: [true, 42, { foo: "bar" }],
} as const;
// => true | 42 | { foo: "bar"}
type Enum = FromSchema<typeof enumSchema>;
type: ["string", "number"]
/ TS는 Union을 통해 타입을 제한시켜야 합니다.