or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-validation.mderror-handling.mdindex.mdjtd-schemas.mdkeywords-vocabularies.mdschema-2019.mdschema-2020.mdschema-management.mdstandalone-generation.mdtypescript-integration.md
tile.json

jtd-schemas.mddocs/

JSON Type Definition (JTD) Schemas

JTD schema validation with built-in serialization and parsing capabilities for high-performance data processing, offering a simpler alternative to JSON Schema with TypeScript-like type definitions.

Capabilities

JTD Ajv Constructor

Creates an Ajv validator instance specifically configured for JSON Type Definition (JTD) schemas with optimized performance and built-in serialization support.

/**
 * Creates Ajv validator for JTD schemas
 * @param options - JTD-specific configuration options
 */
constructor(options?: JTDOptions);

interface JTDOptions extends Omit<CurrentOptions, 
  'strict' | 'allowMatchingProperties' | 'allowUnionTypes' | 'validateFormats' |
  '$data' | 'verbose' | '$comment' | 'formats' | 'loadSchema' |
  'useDefaults' | 'coerceTypes' | 'next' | 'unevaluated' | 'dynamicRef' |
  'defaultMeta' | 'loopRequired' | 'multipleOfPrecision'> {
  verbose?: boolean;
  meta?: boolean;
  inlineRefs?: boolean;
}

Usage Examples:

import AjvJTD from "ajv/dist/jtd";

// Basic JTD validator
const ajv = new AjvJTD();

// JTD validator with custom options
const ajvVerbose = new AjvJTD({
  allErrors: true,
  verbose: true
});

Compile Serializer

Compiles JTD schemas into high-performance serialization functions that convert JavaScript objects to JSON strings with type validation.

/**
 * Compiles JTD schema to serializer function
 * @param schema - JTD schema definition
 * @returns Function that serializes data to JSON string
 */
compileSerializer<T = unknown>(schema: SchemaObject): (data: T) => string;
compileSerializer<T = unknown>(schema: JTDSchemaType<T>): (data: T) => string;

Usage Examples:

import AjvJTD from "ajv/dist/jtd";

const ajv = new AjvJTD();

// User schema definition
const userSchema = {
  properties: {
    id: { type: "uint32" },
    name: { type: "string" },
    email: { type: "string" },
    active: { type: "boolean" },
    balance: { type: "float64" }
  },
  required: ["id", "name", "email"]
};

// Compile serializer
const serializeUser = ajv.compileSerializer(userSchema);

// Serialize data
const userData = {
  id: 123,
  name: "Alice Smith", 
  email: "alice@example.com",
  active: true,
  balance: 1250.75
};

const jsonString = serializeUser(userData);
console.log(jsonString); // '{"id":123,"name":"Alice Smith","email":"alice@example.com","active":true,"balance":1250.75}'

// Type-safe serializer with TypeScript
interface User {
  id: number;
  name: string;
  email: string;
  active?: boolean;
  balance?: number;
}

const typedSchema: JTDSchemaType<User> = {
  properties: {
    id: { type: "uint32" },
    name: { type: "string" },
    email: { type: "string" }
  },
  optionalProperties: {
    active: { type: "boolean" },
    balance: { type: "float64" }
  }
};

const typedSerialize = ajv.compileSerializer<User>(typedSchema);

Compile Parser

Compiles JTD schemas into high-performance parsing functions that convert JSON strings to JavaScript objects with validation.

/**
 * Compiles JTD schema to parser function
 * @param schema - JTD schema definition
 * @returns Parser function that validates and parses JSON strings
 */
compileParser<T = unknown>(schema: SchemaObject): JTDParser<T>;
compileParser<T = unknown>(schema: JTDSchemaType<T>): JTDParser<T>;

interface JTDParser<T> {
  (str: string): T | undefined;
  message?: string;      // Error message if parsing failed
  position?: number;     // Position in string where error occurred
}

Usage Examples:

import AjvJTD from "ajv/dist/jtd";

const ajv = new AjvJTD();

// Product schema
const productSchema = {
  properties: {
    id: { type: "string" },
    name: { type: "string" },
    price: { type: "float64" }
  },
  optionalProperties: {
    description: { type: "string" },
    inStock: { type: "boolean" }
  }
};

// Compile parser
const parseProduct = ajv.compileParser(productSchema);

// Parse valid JSON
const validJson = '{"id":"prod-123","name":"Widget","price":29.99,"inStock":true}';
const product = parseProduct(validJson);

if (product) {
  console.log("Parsed product:", product);
} else {
  console.log("Parse error:", parseProduct.message);
  console.log("Error position:", parseProduct.position);
}

// Parse invalid JSON
const invalidJson = '{"id":"prod-123","name":"Widget","price":"not-a-number"}';
const failedProduct = parseProduct(invalidJson);

if (!failedProduct) {
  console.log("Parse failed:", parseProduct.message); // Type validation error
}

// Type-safe parser
interface Product {
  id: string;
  name: string; 
  price: number;
  description?: string;
  inStock?: boolean;
}

const typedParser = ajv.compileParser<Product>(productSchema);
const typedProduct: Product | undefined = typedParser(validJson);

JTD Schema Types

JTD provides a simpler, more TypeScript-like schema definition format compared to JSON Schema.

// Core JTD schema forms
type JTDSchemaType<T> = 
  | JTDType<T>
  | JTDEnum<T>
  | JTDElements<T>
  | JTDProperties<T>
  | JTDValues<T>
  | JTDUnion<T>
  | JTDRef<T>;

// Primitive types
interface JTDType<T> {
  type: "boolean" | "string" | "timestamp" | 
        "float32" | "float64" | 
        "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32";
  nullable?: boolean;
}

// Enum values
interface JTDEnum<T> {
  enum: string[];
  nullable?: boolean;
}

// Array elements
interface JTDElements<T> {
  elements: JTDSchemaType<T>;
  nullable?: boolean;
}

// Object properties
interface JTDProperties<T> {
  properties?: { [K in keyof T]-?: JTDSchemaType<T[K]> };
  optionalProperties?: { [K in keyof T]?: JTDSchemaType<T[K]> };
  additionalProperties?: boolean;
  nullable?: boolean;
}

// Map/dictionary values
interface JTDValues<T> {
  values: JTDSchemaType<T>;
  nullable?: boolean;
}

// Union types (discriminated)
interface JTDUnion<T> {
  discriminator: string;
  mapping: { [key: string]: JTDSchemaType<T> };
  nullable?: boolean;
}

// References
interface JTDRef<T> {
  ref: string;
  nullable?: boolean;
}

Usage Examples:

import AjvJTD from "ajv/dist/jtd";

const ajv = new AjvJTD();

// Primitive types
const stringSchema = { type: "string" };
const numberSchema = { type: "float64" };
const booleanSchema = { type: "boolean" };
const timestampSchema = { type: "timestamp" };

// Nullable types
const nullableStringSchema = { type: "string", nullable: true };

// Enum schema
const statusSchema = {
  enum: ["active", "inactive", "pending"]
};

// Array schema
const numbersSchema = {
  elements: { type: "int32" }
};

// Object schema with required and optional properties
const userSchema = {
  properties: {
    id: { type: "uint32" },
    username: { type: "string" }
  },
  optionalProperties: {
    email: { type: "string" },
    createdAt: { type: "timestamp" }
  }
};

// Map/dictionary schema
const settingsSchema = {
  values: { type: "string" }
};

// Discriminated union schema
const shapeSchema = {
  discriminator: "type",
  mapping: {
    circle: {
      properties: {
        radius: { type: "float64" }
      }
    },
    rectangle: {
      properties: {
        width: { type: "float64" },
        height: { type: "float64" }
      }
    }
  }
};

// Reference schema with definitions
const personSchema = {
  definitions: {
    address: {
      properties: {
        street: { type: "string" },
        city: { type: "string" },
        zipCode: { type: "string" }
      }
    }
  },
  properties: {
    name: { type: "string" },
    homeAddress: { ref: "address" },
    workAddress: { ref: "address", nullable: true }
  }
};

JTD vs JSON Schema

JTD offers several advantages for certain use cases:

Performance Benefits

import AjvJTD from "ajv/dist/jtd";
import Ajv from "ajv";

// JTD - simpler, faster
const jtdAjv = new AjvJTD();
const jtdSchema = {
  properties: {
    name: { type: "string" },
    age: { type: "uint8" }
  }
};

// JSON Schema - more features, more overhead
const jsonAjv = new Ajv();
const jsonSchema = {
  type: "object",
  properties: {
    name: { type: "string" },
    age: { type: "integer", minimum: 0, maximum: 255 }
  },
  required: ["name", "age"],
  additionalProperties: false
};

// JTD parsing and serialization
const parse = jtdAjv.compileParser(jtdSchema);
const serialize = jtdAjv.compileSerializer(jtdSchema);

const jsonStr = '{"name":"Alice","age":30}';
const data = parse(jsonStr);         // Fast parsing with validation
const backToJson = serialize(data);  // Fast serialization

Type Safety Benefits

import AjvJTD, { JTDSchemaType } from "ajv/dist/jtd";

// Define TypeScript interface
interface APIResponse {
  success: boolean;
  data: {
    users: Array<{
      id: number;
      name: string;
      email?: string;
    }>;
  };
  meta: {
    total: number;
    page: number;
  };
}

// JTD schema with full type safety
const responseSchema: JTDSchemaType<APIResponse> = {
  properties: {
    success: { type: "boolean" },
    data: {
      properties: {
        users: {
          elements: {
            properties: {
              id: { type: "uint32" },
              name: { type: "string" }
            },
            optionalProperties: {
              email: { type: "string" }
            }
          }
        }
      }
    },
    meta: {
      properties: {
        total: { type: "uint32" },
        page: { type: "uint32" }
      }
    }
  }
};

const ajv = new AjvJTD();
const parseResponse = ajv.compileParser<APIResponse>(responseSchema);
const serializeResponse = ajv.compileSerializer<APIResponse>(responseSchema);

Error Handling

JTD provides simplified but effective error reporting:

import AjvJTD from "ajv/dist/jtd";

const ajv = new AjvJTD();

const schema = {
  properties: {
    name: { type: "string" },
    age: { type: "uint8" }
  }
};

const validate = ajv.compile(schema);
const parse = ajv.compileParser(schema);

// Validation errors
const invalidData = { name: 123, age: "not-a-number" };
const valid = validate(invalidData);

if (!valid) {
  console.log("Validation errors:", validate.errors);
}

// Parse errors
const invalidJson = '{"name":"Alice","age":"too-old"}';
const parsed = parse(invalidJson);

if (!parsed) {
  console.log("Parse error:", parse.message);
  console.log("Error position:", parse.position);
}