1.1.8 • Published 7 months ago
@imhonglu/json-schema v1.1.8
@imhonglu/json-schema
Introduction
- A library that complies with JSON Schema 2020-12-draft specification
- Validated based on JSON-Schema-test-suite
- Supports static type inference based on schema definitions

Table of Contents
Features
- TypeScript static type checking support for schema definitions
- Smart type inference
- Required/optional field inference based on
requiredproperty - Type inference for fields with
defaultvalues / function type support - Recursive type inference for nested objects
- Required/optional field inference based on
- Class-based schema definition support
- Custom features
- Schema validation message customization
- Custom error handling
- Validation rule extension support
Implementation Status
Currently, 1,487 out of 1,563 test cases have passed (95.1%)
Excluded items:
defs: Schema definition related tests, excluded as they are not related to validationformat: Excluded as it belongs to the optional category
Unsupported items:
anchorrefRemotevocabularydynamicRefoptional/anchoroptional/dynamicRefoptional/dependencies-compatibilityoptional/format/relative-json-pointeroptional/format/json-pointer
Installation
npm install @imhonglu/json-schemaUsage
Basic Schema Definition
// address.ts
import { createSchemaClass } from "@imhonglu/json-schema";
export class Address extends createSchemaClass({
type: "object",
properties: {
street: { type: "string" },
city: { type: "string" },
zip: { type: "string" },
},
// Define street property as required
required: ["street"],
}) {}
// ✅ Type inference result:
// {
// street: string; // required
// city?: string; // optional
// zip?: string; // optional
// }Nested Schema
// person.ts
import { createSchemaClass } from "@imhonglu/json-schema";
import { Address } from "./address.js";
export class Person extends createSchemaClass({
type: "object",
properties: {
name: { type: "string" },
address: Address, // Nested Address schema
createdAt: {
type: "string",
default: () => new Date().toISOString(),
},
// String field that allows null
deletedAt: {
type: ["string", "null"],
default: null,
},
},
required: ["name", "createdAt", "deletedAt"],
}) {}
// ✅ Type inference result:
// {
// name: string; // required
// address?: Address; // optional
// createdAt: string; // required
// deletedAt: string | null; // required
// }Usage with new
import { Person } from "./person.js";
// Create instance with object literal
const johnDoe = new Person({
name: "John Doe",
address: {
street: "123 Main St",
city: "Toronto",
zip: "M5H 2N2",
},
});
// ✅ Result:
// {
// name: 'John Doe',
// address: Address {
// street: '123 Main St',
// city: 'Toronto',
// zip: 'M5H 2N2'
// },
// deletedAt: null
// }
// ✅ Property access
console.log(johnDoe.name); // 'John Doe'
console.log(johnDoe.address?.street); // '123 Main St'
console.log(johnDoe.deletedAt); // null
// ✅ Using directly created Address instance
const maryDoe = new Person({
name: "Mary Doe",
address: new Address({
street: "456 Main St",
city: "Toronto",
zip: "M5H 2N2",
}),
});Parsing with parse
The parse method creates a schema instance by parsing a string.
const person = Person.parse('{ "name": "John" }'); // PersonParsing with safeParse
You can safely parse using the safeParse method.
const person = Person.safeParse('{ "name": "John" }'); // SafeResult<Person>
if (person.success) {
console.log(person.data); // Person
} else {
console.error(person.error); // ValidationFailedError
}Serializing with JSON.stringify
The toJSON method is implemented, allowing serialization through JSON.stringify.
const person = new Person({ name: "John" });
const json = JSON.stringify(person); // '{"name":"John","deletedAt":null}'Known Issues
Type Inference Limitations for Inline Schemas
There is an issue where type inference for the required property doesn't work properly for inline-defined sub-schemas.
For example:
class Person extends createSchemaClass({
type: "object",
properties: {
name: { type: "string" },
address: {
type: "object",
properties: {
street: { type: "string" },
city: { type: "string" },
zip: { type: "string" },
},
required: ["street"], // This constraint is not properly applied
},
},
required: ["name"],
}) {}
// ❌ No type error due to incorrect inference
const person = new Person({
name: "John Doe",
address: {}, // No type error despite street being required
});Solution: Separate into Independent Classes
To resolve this issue, sub-schemas should be defined as separate classes.
// ✅ Separate into independent class
class Address extends createSchemaClass({
type: "object",
properties: {
street: { type: "string" },
city: { type: "string" },
zip: { type: "string" },
},
required: ["street"],
}) {}
class Person extends createSchemaClass({
type: "object",
properties: {
name: { type: "string" },
address: Address, // Reference Address class
},
required: ["name"],
}) {}
const person = new Person({
name: "John Doe",
address: {}, // ✅ Type error: street property is required
});API Reference
Core API
- Schema - Base class for all schema types as an implementation of JSON Schema
- createSchemaClass - Creates a type-safe schema class from JSON Schema definition
- InferSchemaInputType - Infers input type from schema definition
- InferSchemaType - Infers type from schema definition
- InferSchema - Infers schema type
- ConstSchema - Defines a schema that allows only a single fixed value
- EnumSchema - Defines a schema that allows one of predefined values
- TypeSchema - Schema that defines basic JSON data types
- SchemaVariant - Includes all schema types supported by the library
JSON Schema Specification Types
- JsonSchema - JSON Schema type including Object Schema and Boolean Schema types
- ObjectSchema - Object Schema
- BooleanSchema - Boolean Schema
1.1.8
7 months ago
1.1.7
8 months ago
1.1.6
8 months ago
1.1.5
8 months ago
1.1.4
8 months ago
1.1.3
8 months ago
1.1.2
8 months ago
1.1.1
9 months ago
1.1.0
9 months ago
1.0.8
9 months ago
1.0.7
9 months ago
1.0.6
9 months ago
1.0.5
9 months ago
1.0.4
9 months ago
1.0.3
10 months ago
1.0.2
10 months ago
1.0.1
10 months ago
1.0.0
10 months ago