create-schema
TypeScript-first schema validation with static type inference
Installation
To install:
npm install create-schema
⚠️ IMPORTANT: You must enable strict
mode in your tsconfig.json
. This is a best practice for all TypeScript projects.
{
"compilerOptions": {
"strict": true
}
}
Usage
Schema
const addressSchema = createSchema({
street: 'string',
number: 'int?',
});
const schemaDefinition = {
name: 'string',
email: 'email?',
age: 'int?',
notes: '[int]?',
letter: ['a', 'b', 'c'],
letterOptionalList: {
type: 'enum',
def: ['x', 'y', 'z'],
optional: true,
list: true,
},
address: {
type: addressSchema,
optional: true,
},
} as const;
const userSchema = createSchema(schemaDefinition);
expect(() => userSchema.parse({ name: 'Antonio', letter: 'x' })).toThrow(
`field "letter": accepted: 'a' or 'b' or 'c', found x.`
);
const parsed = userSchema.parse({ name: 'antonio', letter: 'a' });
type InferType = typeof parsed;
assert<
IsExact<
InferType,
{
name: string;
email: string | undefined;
age: number | undefined;
notes: number[] | undefined;
letter: 'a' | 'b' | 'c';
letterOptionalList: ('x' | 'y' | 'z')[] | undefined;
address:
| {
street: string;
number: number | undefined;
}
| undefined;
}
>
>(true);
schemaToTypescript
Returns a string of an interface representing a DarchSchema;
import { schemaToTypescript } from 'create-schema';
const interfaceTxt = await schemaToTypescript('User', userSchema);
expect(interfaceTxt).toBe(
`/* tslint:disable */
/**
* This file was automatically generated.
* DO NOT MODIFY IT BY HAND.
*/
export type EnumLetterUser = "a" | "b" | "c";
export type Enum_SubLetterOptionalList = "x" | "y" | "z";
export interface User {
name: string;
email?: Email;
age?: number;
notes?: number[];
letter: EnumLetterUser;
letterOptionalList?: Enum_SubLetterOptionalList[];
address?: {
street: string;
number?: number;
[k: string]: unknown;
};
[k: string]: unknown;
}
`
);
schemaToJSON
Receives a DarchSchema and returns a json-schema
import { schemaToJSON } from 'create-schema';
const jsonSchema = schemaToJSON('User', userSchema);
expect(jsonSchema).toEqual({
properties: {
address: {
properties: {
number: {
type: 'integer',
},
street: {
type: 'string',
},
},
required: ['street'],
title: '',
type: 'object',
},
age: {
type: 'integer',
},
email: {
tsType: 'Email',
type: 'string',
},
letter: {
enum: ['a', 'b', 'c'],
title: 'EnumLetterUser',
type: 'string',
},
letterOptionalList: {
items: {
enum: ['x', 'y', 'z'],
title: 'Enum__subLetterOptionalList',
type: 'string',
},
type: 'array',
},
name: {
type: 'string',
},
notes: {
items: {
type: 'integer',
},
type: 'array',
},
},
required: ['name', 'letter'],
title: 'User',
type: 'object',
});
TODO