Skip to main content
Deno 2 is finally here šŸŽ‰ļø
Learn more

TypeBox

JSON Schema Type Builder with Static Type Resolution for TypeScript



npm version GitHub CI

Install

Node

$ npm install @sinclair/typebox --save

Deno

import { Static, Type } from 'https://deno.land/x/typebox/src/typebox.ts'

Example

import { Static, Type } from '@sinclair/typebox'

const T = Type.String()     // const T = { type: 'string' }

type T = Static<typeof T>   // type T = string

Overview

TypeBox is a type builder library that creates in-memory JSON Schema objects that can be statically inferred as TypeScript types. The schemas produced by this library are designed to match the static type checking rules of the TypeScript compiler. TypeBox allows one to compose unified types that can be statically asserted by the TypeScript compiler as well as runtime asserted using standard JSON Schema validation.

TypeBox can be used as a simple tool to build up complex schemas or integrated into RPC or REST services to help validate JSON data received over the wire. It can be used in both TypeScript and JavaScript environments.

License MIT

Contents

Usage

The following demonstrates TypeBoxā€™s general usage.

import { Static, Type } from '@sinclair/typebox'

//--------------------------------------------------------------------------------------------
//
// Let's say you have the following type ...
//
//--------------------------------------------------------------------------------------------

type T = {
  id: string,
  name: string,
  timestamp: number
}

//--------------------------------------------------------------------------------------------
//
// ... you can express this type in the following way.
//
//--------------------------------------------------------------------------------------------

const T = Type.Object({                              // const T = {
  id: Type.String(),                                 //   type: 'object',
  name: Type.String(),                               //   properties: { 
  timestamp: Type.Integer()                          //     id: { 
})                                                   //       type: 'string' 
                                                     //     },
                                                     //     name: { 
                                                     //       type: 'string' 
                                                     //     },
                                                     //     timestamp: { 
                                                     //       type: 'integer' 
                                                     //     }
                                                     //   }, 
                                                     //   required: [
                                                     //     "id",
                                                     //     "name",
                                                     //     "timestamp"
                                                     //   ]
                                                     // } 

//--------------------------------------------------------------------------------------------
//
// ... then infer back to the original static type this way.
//
//--------------------------------------------------------------------------------------------

type T = Static<typeof T>                            // type T = {
                                                     //   id: string,
                                                     //   name: string,
                                                     //   timestamp: number
                                                     // }

//--------------------------------------------------------------------------------------------
//
// ... then use the type both as JSON schema and as a TypeScript type.
//
//--------------------------------------------------------------------------------------------

function receive(value: T) {                         // ... as a Type

  if(JSON.validate(T, value)) {                      // ... as a Schema
        // ok...
  }
}

Types

The following table outlines the TypeBox mappings between TypeScript and JSON schema.

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
ā”‚ TypeBox                        ā”‚ TypeScript                  ā”‚ JSON Schema                    ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Any()           ā”‚ type T = any                ā”‚ const T = { }                  ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Unknown()       ā”‚ type T = unknown            ā”‚ const T = { }                  ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.String()        ā”‚ type T = string             ā”‚ const T = {                    ā”‚
ā”‚                                ā”‚                             ā”‚   type: 'string'               ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Number()        ā”‚ type T = number             ā”‚ const T = {                    ā”‚
ā”‚                                ā”‚                             ā”‚   type: 'number'               ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Integer()       ā”‚ type T = number             ā”‚ const T = {                    ā”‚
ā”‚                                ā”‚                             ā”‚   type: 'integer'              ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Boolean()       ā”‚ type T = boolean            ā”‚ const T = {                    ā”‚
ā”‚                                ā”‚                             ā”‚   type: 'boolean'              ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Null()          ā”‚ type T = null               ā”‚ const T = {                    ā”‚
ā”‚                                ā”‚                             ā”‚    type: 'null'                ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.RegEx(/foo/)    ā”‚ type T = string             ā”‚ const T = {                    ā”‚
ā”‚                                ā”‚                             ā”‚    type: 'string',             ā”‚
ā”‚                                ā”‚                             ā”‚    pattern: 'foo'              ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Literal(42)     ā”‚ type T = 42                 ā”‚ const T = {                    ā”‚
ā”‚                                ā”‚                             ā”‚    const: 42                   ā”‚
ā”‚                                ā”‚                             ā”‚    type: 'number'              ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Array(          ā”‚ type T = number[]           ā”‚ const T = {                    ā”‚
ā”‚   Type.Number()                ā”‚                             ā”‚   type: 'array',               ā”‚
ā”‚ )                              ā”‚                             ā”‚   items: {                     ā”‚
ā”‚                                ā”‚                             ā”‚     type: 'number'             ā”‚
ā”‚                                ā”‚                             ā”‚   }                            ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Object({        ā”‚ type T = {                  ā”‚ const T = {                    ā”‚
ā”‚   x: Type.Number(),            ā”‚   x: number,                ā”‚   type: 'object',              ā”‚
ā”‚   y: Type.Number()             ā”‚   y: number                 ā”‚   properties: {                ā”‚
ā”‚ })                             ā”‚ }                           ā”‚      x: {                      ā”‚
ā”‚                                ā”‚                             ā”‚        type: 'number'          ā”‚
ā”‚                                ā”‚                             ā”‚      },                        ā”‚
ā”‚                                ā”‚                             ā”‚      y: {                      ā”‚
ā”‚                                ā”‚                             ā”‚        type: 'number'          ā”‚
ā”‚                                ā”‚                             ā”‚      }                         ā”‚
ā”‚                                ā”‚                             ā”‚   },                           ā”‚
ā”‚                                ā”‚                             ā”‚   required: ['x', 'y']         ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Tuple([         ā”‚ type T = [number, number]   ā”‚ const T = {                    ā”‚
ā”‚   Type.Number(),               ā”‚                             ā”‚   type: 'array',               ā”‚
ā”‚   Type.Number()                ā”‚                             ā”‚   items: [{                    ā”‚
ā”‚ ])                             ā”‚                             ā”‚      type: 'number'            ā”‚
ā”‚                                ā”‚                             ā”‚    }, {                        ā”‚
ā”‚                                ā”‚                             ā”‚      type: 'number'            ā”‚
ā”‚                                ā”‚                             ā”‚    }],                         ā”‚
ā”‚                                ā”‚                             ā”‚    additionalItems: false,     ā”‚
ā”‚                                ā”‚                             ā”‚    minItems: 2,                ā”‚
ā”‚                                ā”‚                             ā”‚    maxItems: 2,                ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ enum Foo {                     ā”‚ enum Foo {                  ā”‚ const T = {                    ā”‚
ā”‚   A,                           ā”‚   A,                        ā”‚   anyOf: [{                    ā”‚
ā”‚   B                            ā”‚   B                         ā”‚     type: 'number',            ā”‚
ā”‚ }                              ā”‚ }                           ā”‚     const: 0                   ā”‚
ā”‚                                ā”‚                             ā”‚   }, {                         ā”‚
ā”‚ const T = Type.Enum(Foo)       ā”‚ type T = Foo                ā”‚     type: 'number',            ā”‚
ā”‚                                ā”‚                             ā”‚     const: 1                   ā”‚
ā”‚                                ā”‚                             ā”‚   }]                           ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.KeyOf(          ā”‚ type T = keyof {            ā”‚ const T = {                    ā”‚
ā”‚   Type.Object({                ā”‚   x: number,                ā”‚   anyOf: [{                    ā”‚
ā”‚     x: Type.Number(),          ā”‚   y: number                 ā”‚     type: 'string',            ā”‚
ā”‚     y: Type.Number()           ā”‚ }                           ā”‚     const: 'x'                 ā”‚
ā”‚   })                           ā”‚                             ā”‚   }, {                         ā”‚
ā”‚ )                              ā”‚                             ā”‚     type: 'string',            ā”‚
ā”‚                                ā”‚                             ā”‚     const: 'y',                ā”‚
ā”‚                                ā”‚                             ā”‚   }]                           ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Union([         ā”‚ type T = string | number    ā”‚ const T = {                    ā”‚
ā”‚   Type.String(),               ā”‚                             ā”‚   anyOf: [{                    ā”‚
ā”‚   Type.Number()                ā”‚                             ā”‚      type: 'string'            ā”‚
ā”‚ ])                             ā”‚                             ā”‚   }, {                         ā”‚
ā”‚                                ā”‚                             ā”‚      type: 'number'            ā”‚
ā”‚                                ā”‚                             ā”‚   }]                           ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Intersect([     ā”‚ type T = {                  ā”‚ const T = {                    ā”‚
ā”‚   Type.Object({                ā”‚   x: number                 ā”‚   type: 'object',              ā”‚
ā”‚     x: Type.Number()           ā”‚ } & {                       ā”‚   properties: {                ā”‚
ā”‚   }),                          ā”‚   y: number                 ā”‚     x: {                       ā”‚
ā”‚   Type.Object({                ā”‚ }                           ā”‚       type: 'number'           ā”‚
ā”‚     y: Type.Number()           ā”‚                             ā”‚     },                         ā”‚
ā”‚   })                           ā”‚                             ā”‚     y: {                       ā”‚
ā”‚ ])                             ā”‚                             ā”‚       type: 'number'           ā”‚
ā”‚                                ā”‚                             ā”‚     }                          ā”‚
ā”‚                                ā”‚                             ā”‚   },                           ā”‚
ā”‚                                ā”‚                             ā”‚   required: ['x', 'y']         ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Record(         ā”‚ type T = Record<            ā”‚ const T = {                    ā”‚
ā”‚   Type.String(),               ā”‚   string,                   ā”‚   type: 'object',              ā”‚
ā”‚   Type.Number()                ā”‚   number,                   ā”‚   patternProperties: {         ā”‚
ā”‚ )                              ā”‚ >                           ā”‚     '^.*$': {                  ā”‚
ā”‚                                ā”‚                             ā”‚       type: 'number'           ā”‚
ā”‚                                ā”‚                             ā”‚     }                          ā”‚
ā”‚                                ā”‚                             ā”‚   }                            ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Partial(        ā”‚ type T = Partial<{          ā”‚ const T = {                    ā”‚
ā”‚   Type.Object({                ā”‚   x: number,                ā”‚   type: 'object',              ā”‚
ā”‚     x: Type.Number(),          ā”‚   y: number                 ā”‚   properties: {                ā”‚
ā”‚     y: Type.Number()           | }>                          ā”‚     x: {                       ā”‚
ā”‚   })                           ā”‚                             ā”‚       type: 'number'           ā”‚
ā”‚ )                              ā”‚                             ā”‚     },                         ā”‚
ā”‚                                ā”‚                             ā”‚     y: {                       ā”‚
ā”‚                                ā”‚                             ā”‚       type: 'number'           ā”‚
ā”‚                                ā”‚                             ā”‚     }                          ā”‚
ā”‚                                ā”‚                             ā”‚   }                            ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Required(       ā”‚ type T = Required<{         ā”‚ const T = {                    ā”‚
ā”‚   Type.Object({                ā”‚   x?: number,               ā”‚   type: 'object',              ā”‚
ā”‚     x: Type.Optional(          ā”‚   y?: number                ā”‚   properties: {                ā”‚
ā”‚       Type.Number()            | }>                          ā”‚     x: {                       ā”‚
ā”‚     ),                         ā”‚                             ā”‚       type: 'number'           ā”‚
ā”‚     y: Type.Optional(          ā”‚                             ā”‚     },                         ā”‚
ā”‚       Type.Number()            ā”‚                             ā”‚     y: {                       ā”‚
ā”‚     )                          ā”‚                             ā”‚       type: 'number'           ā”‚
ā”‚   })                           ā”‚                             ā”‚     }                          ā”‚
ā”‚ )                              ā”‚                             ā”‚   },                           ā”‚
ā”‚                                ā”‚                             ā”‚   required: ['x', 'y']         ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Pick(           ā”‚ type T = Pick<{             ā”‚ const T = {                    ā”‚
ā”‚   Type.Object({                ā”‚   x: number,                ā”‚   type: 'object',              ā”‚
ā”‚     x: Type.Number(),          ā”‚   y: number                 ā”‚   properties: {                ā”‚
ā”‚     y: Type.Number(),          | }, 'x'>                     ā”‚     x: {                       ā”‚
ā”‚   }), ['x']                    ā”‚                             ā”‚       type: 'number'           ā”‚
ā”‚ )                              ā”‚                             ā”‚     }                          ā”‚
ā”‚                                ā”‚                             ā”‚   },                           ā”‚
ā”‚                                ā”‚                             ā”‚   required: ['x']              ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Omit(           ā”‚ type T = Omit<{             ā”‚ const T = {                    ā”‚
ā”‚   Type.Object({                ā”‚   x: number,                ā”‚   type: 'object',              ā”‚
ā”‚     x: Type.Number(),          ā”‚   y: number                 ā”‚   properties: {                ā”‚
ā”‚     y: Type.Number(),          | }, 'x'>                     ā”‚     y: {                       ā”‚
ā”‚   }), ['x']                    ā”‚                             ā”‚       type: 'number'           ā”‚
ā”‚ )                              ā”‚                             ā”‚     }                          ā”‚
ā”‚                                ā”‚                             ā”‚   },                           ā”‚
ā”‚                                ā”‚                             ā”‚   required: ['y']              ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Modifiers

TypeBox provides modifiers that can be applied to an objects properties. This allows for optional and readonly to be applied to that property. The following table illustates how they map between TypeScript and JSON Schema.

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
ā”‚ TypeBox                        ā”‚ TypeScript                  ā”‚ JSON Schema                    ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Object({        ā”‚ type T = {                  ā”‚ const T = {                    ā”‚
ā”‚   name: Type.Optional(         ā”‚   name?: string,            ā”‚   type: 'object',              ā”‚
ā”‚     Type.String(),             ā”‚ }                           ā”‚   properties: {                ā”‚
ā”‚   )                            ā”‚                             ā”‚      name: {                   ā”‚
ā”‚ })  	                         ā”‚                             ā”‚        type: 'string'          ā”‚
ā”‚                                ā”‚                             ā”‚      }                         ā”‚
ā”‚                                ā”‚                             ā”‚   }                            ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Object({        ā”‚ type T = {                  ā”‚ const T = {                    ā”‚
ā”‚   name: Type.Readonly(         ā”‚   readonly name: string,    ā”‚   type: 'object',              ā”‚
ā”‚     Type.String(),             ā”‚ }                           ā”‚   properties: {                ā”‚
ā”‚   )                            ā”‚                             ā”‚     name: {                    ā”‚
ā”‚ })  	                         ā”‚                             ā”‚       type: 'string'           ā”‚
ā”‚                                ā”‚                             ā”‚     }                          ā”‚
ā”‚                                ā”‚                             ā”‚   },                           ā”‚
ā”‚                                ā”‚                             ā”‚   required: ['name']           ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Object({        ā”‚ type T = {                  ā”‚ const T = {                    ā”‚
ā”‚   name: Type.ReadonlyOptional( ā”‚   readonly name?: string    ā”‚   type: 'object',              ā”‚
ā”‚     Type.String(),             ā”‚ }                           ā”‚   properties: {                ā”‚
ā”‚   )                            ā”‚                             ā”‚     name: {                    ā”‚
ā”‚ })  	                         ā”‚                             ā”‚       type: 'string'           ā”‚
ā”‚                                ā”‚                             ā”‚     }                          ā”‚
ā”‚                                ā”‚                             ā”‚   }                            ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Options

You can pass additional JSON schema options on the last argument of any given type. The following are some examples.

// string must be an email
const T = Type.String({ format: 'email' })

// number must be a multiple of 2
const T = Type.Number({ multipleOf: 2 })

// array must have at least 5 integer values
const T = Type.Array(Type.Integer(), { minItems: 5 })

Extended Types

In addition to JSON schema types, TypeBox provides several extended types that allow for function and constructor types to be composed. These additional types are not valid JSON Schema and will not validate using typical JSON Schema validation. However, these types can be used to frame JSON schema and describe callable interfaces that may receive JSON validated data. These types are as follows.

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
ā”‚ TypeBox                        ā”‚ TypeScript                  ā”‚ Extended Schema                ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Constructor([   ā”‚ type T = new (              ā”‚ const T = {                    ā”‚
ā”‚   Type.String(),               ā”‚  arg0: string,              ā”‚   type: 'constructor'          ā”‚
ā”‚   Type.Number()                ā”‚  arg1: number               ā”‚   arguments: [{                ā”‚
ā”‚ ], Type.Boolean())             ā”‚ ) => boolean                ā”‚     type: 'string'             ā”‚
ā”‚                                ā”‚                             ā”‚   }, {                         ā”‚
ā”‚                                ā”‚                             ā”‚     type: 'number'             ā”‚
ā”‚                                ā”‚                             ā”‚   }],                          ā”‚
ā”‚                                ā”‚                             ā”‚   returns: {                   ā”‚
ā”‚                                ā”‚                             ā”‚     type: 'boolean'            ā”‚
ā”‚                                ā”‚                             ā”‚   }                            ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Function([      ā”‚ type T = (                  ā”‚ const T = {                    ā”‚
|   Type.String(),               ā”‚  arg0: string,              ā”‚   type : 'function',           ā”‚
ā”‚   Type.Number()                ā”‚  arg1: number               ā”‚   arguments: [{                ā”‚
ā”‚ ], Type.Boolean())             ā”‚ ) => boolean                ā”‚     type: 'string'             ā”‚
ā”‚                                ā”‚                             ā”‚   }, {                         ā”‚
ā”‚                                ā”‚                             ā”‚     type: 'number'             ā”‚
ā”‚                                ā”‚                             ā”‚   }],                          ā”‚
ā”‚                                ā”‚                             ā”‚   returns: {                   ā”‚
ā”‚                                ā”‚                             ā”‚     type: 'boolean'            ā”‚
ā”‚                                ā”‚                             ā”‚   }                            ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Uint8Array()    ā”‚ type T = Uint8Array         ā”‚ const T = {                    ā”‚
ā”‚                                ā”‚                             ā”‚   type: 'object',              ā”‚
ā”‚                                ā”‚                             ā”‚   specialized: 'Uint8Array'    ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Promise(        ā”‚ type T = Promise<string>    ā”‚ const T = {                    ā”‚
ā”‚   Type.String()                ā”‚                             ā”‚   type: 'promise',             ā”‚
ā”‚ )                              ā”‚                             ā”‚   item: {                      ā”‚
ā”‚                                ā”‚                             ā”‚     type: 'string'             ā”‚
ā”‚                                ā”‚                             ā”‚   }                            ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Undefined()     ā”‚ type T = undefined          ā”‚ const T = {                    ā”‚
ā”‚                                ā”‚                             ā”‚   type: 'object'               ā”‚
ā”‚                                ā”‚                             ā”‚   specialized: 'Undefined'     ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ const T = Type.Void()          ā”‚ type T = void               ā”‚ const T = {                    ā”‚
ā”‚                                ā”‚                             ā”‚   type: 'null'                 ā”‚
ā”‚                                ā”‚                             ā”‚ }                              ā”‚
ā”‚                                ā”‚                             ā”‚                                ā”‚
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Reference Types

Types can be referenced with Type.Ref(...). To reference a type, the target type must specify an $id.

const T = Type.String({ $id: 'T' })                  // const T = {
                                                     //    $id: 'T',
                                                     //    type: 'string'
                                                     // }
                                             
const R = Type.Ref(T)                                // const R = {
                                                     //    $ref: 'T'
                                                     // }

Recursive Types

Recursive types can be created with the Type.Recursive(...) function.

const Node = Type.Recursive(Node => Type.Object({    // const Node = {
  id:    Type.String(),                              //   $id: "Node",
  nodes: Type.Array(Node),                           //   type: "object",
}), { $id: 'Node' })                                 //   properties: {
                                                     //     id: {
                                                     //       "type": "string"
                                                     //     },
                                                     //     nodes: {
                                                     //       type: "array",
                                                     //       items: {
                                                     //         $ref: "Node"
                                                     //       }
                                                     //     }
                                                     //   },
                                                     //   required: [
                                                     //     "id",
                                                     //     "nodes"
                                                     //   ]
                                                     // }

type Node = Static<typeof Node>                      // type Node = {
                                                     //   id: string
                                                     //   nodes: ...
                                                     // }

function visit(node: Node) {
  for(const inner of node.nodes) {
    visit(inner)
  }
}

Generic Types

Generic types can be created using functions. The following creates a generic Nullable<T> type.

import { Type, Static, TSchema } from '@sinclair/typebox'

const Nullable = <T extends TSchema>(type: T) => Type.Union([type, Type.Null()])

const T = Nullable(Type.String())                    // const T = {
                                                     //   anyOf: [{
                                                     //     type: 'string'
                                                     //   }, {
                                                     //     type: 'null'
                                                     //   }]
                                                     // }

type T = Static<typeof T>                            // type T = string | null

const U = Nullable(Type.Number())                    // const U = {
                                                     //   anyOf: [{
                                                     //     type: 'number'
                                                     //   }, {
                                                     //     type: 'null'
                                                     //   }]
                                                     // }

type U = Static<typeof U>                            // type U = number | null

Unsafe Types

In some cases, you may need schema definitions that are not provided by TypeBox. In these scenarios, itā€™s common to want to define your own schema and static type inference rules. The Type.Unsafe(...) function provides this functionality, allowing you to specify both schema representation and a static type to infer. Consider the following which defines a number schema, but will infer as a string.

const T = Type.Unsafe<string>({ type: 'number' })    // const T = {
                                                     //   type: 'number'
                                                     // }

type T = Static<typeof T>                            // type T = string

The Type.Unsafe(...) function can be used with function generics to create custom schema representations for validators requiring specific schema representations. An example of which would be OpenAPIā€™s nullable and string-enum representations which are not provided by TypeBox by default. The following demonstrates creating these schemas using the Type.Unsafe(...) function.

import { Type, Static, TSchema } from '@sinclair/typebox'

//--------------------------------------------------------------------------------------------
//
// Nullable<T>
//
//--------------------------------------------------------------------------------------------

function Nullable<T extends TSchema>(schema: T) {
  return Type.Unsafe<Static<T> | null>({ ...schema, nullable: true })
}

const T = Nullable(Type.String())                    // const T = {
                                                     //   type: 'string',
                                                     //   nullable: true
                                                     // }

type T = Static<typeof T>                            // type T = string | null

//--------------------------------------------------------------------------------------------
//
// StringUnion<[...]>
//
//--------------------------------------------------------------------------------------------

function StringEnum<T extends string[]>(values: [...T]) {
  return Type.Unsafe<T[number]>({ enum: values })
}

const T = StringEnum(['A', 'B', 'C'])                // const T = {
                                                     //   enum: ['A', 'B', 'C']
                                                     // }

type T = Static<typeof T>                            // type T = 'A' | 'B' | 'C'

Values

TypeBox can construct default values for types. TypeBox will create reasonable defaults for any given type, or produce values based on the schemas the default value if specified.

import { Value } from '@sinclair/typebox/value'
import { Type }  from '@sinclair/typebox'

const T = Type.Object({
  x: Type.Number({ default: 1 }),
  y: Type.Number({ default: 2 }),
  z: Type.Number()
})

const V = Value.Create(T)                            // const V = {
                                                     //   x: 1,
                                                     //   y: 2,
                                                     //   z: 0
                                                     // }

Guards

In some scenarios it may be helpful to test if an object is a valid TypeBox type. You can use the TypeGuard module to check an object conforms to a valid TypeBox schema representation. Consider the following.

import { TypeGuard } from '@sinclair/typebox/guard'
import { Type }  from '@sinclair/typebox'

const T: any = Type.String()                         // T is any

const { type } = T                                   // unsafe: type is any

if(TypeGuard.TString(T)) {
    
  const { type } = T                                 // safe: type is 'string'
}

Strict

TypeBox schemas contain the Kind and Modifier symbol properties. These properties are provided to enable runtime type reflection on schemas, as well as helping TypeBox internally compose types. These properties are not strictly valid JSON schema; so in some cases it may be desirable to omit them. TypeBox provides a Type.Strict() function that will omit these properties if necessary.

const T = Type.Object({                              // const T = {
  name: Type.Optional(Type.String())                 //   [Kind]: 'Object',
})                                                   //   type: 'object',
                                                     //   properties: {
                                                     //     name: {
                                                     //       [Kind]: 'String',
                                                     //       type: 'string',
                                                     //       [Modifier]: 'Optional'
                                                     //     }
                                                     //   }
                                                     // }

const U = Type.Strict(T)                             // const U = {
                                                     //   type: 'object', 
                                                     //   properties: { 
                                                     //     name: { 
                                                     //       type: 'string' 
                                                     //     } 
                                                     //   } 
                                                     // }

Validation

TypeBox schemas target JSON Schema draft 6 so any validator capable of draft 6 should be fine. A good library to use for validation in JavaScript environments is AJV. The following example shows setting up AJV 7 to work with TypeBox.

$ npm install ajv ajv-formats --save
//--------------------------------------------------------------------------------------------
//
// Import TypeBox and AJV
//
//--------------------------------------------------------------------------------------------

import { Type }   from '@sinclair/typebox'
import addFormats from 'ajv-formats'
import Ajv        from 'ajv'

//--------------------------------------------------------------------------------------------
//
// Setup AJV validator with the following options and formats
//
//--------------------------------------------------------------------------------------------

const ajv = addFormats(new Ajv({}), [
  'date-time', 
  'time', 
  'date', 
  'email',  
  'hostname', 
  'ipv4', 
  'ipv6', 
  'uri', 
  'uri-reference', 
  'uuid',
  'uri-template', 
  'json-pointer', 
  'relative-json-pointer', 
  'regex'
])

//--------------------------------------------------------------------------------------------
//
// Create a TypeBox type
//
//--------------------------------------------------------------------------------------------

const Vector = Type.Object({
  x: Type.Number(),
  y: Type.Number(),
  z: Type.Number(),
}, { additionalProperties: false })

//--------------------------------------------------------------------------------------------
//
// Validate Data
//
//--------------------------------------------------------------------------------------------

const OK = ajv.validate(Vector, { 
  x: 1,
  y: 2,
  z: 3
}) // -> true

Please refer to the official AJV documentation for additional information on using AJV.

Compiler

TypeBox includes a specialized type compiler that can be used as a runtime type checker in absense of a JSON Schema validator. This compiler is optimized for high throughput validation scenarios and generally performs better than AJV for most structural checks. Please note that this compiler is not fully JSON Schema compliant and is limited to TypeBox types only. The TypeCompiler contains a Compile(T) function that returns a TypeCheck<T> object that can be used to test the validity of a value as well as obtain errors.

import { TypeCompiler } from '@sinclair/typebox/compiler'
import { Type } from '@sinclair/typebox'

const T = Type.Object({
  x: Type.Number(),
  y: Type.Number(),
  z: Type.Number()
})

const C = TypeCompiler.Compile(T)

const OK = C.Check({ 
  x: 1, 
  y: 2, 
  z: 3 
}) // -> true

Errors can be obtained by calling the Errors(...) function. This function returns an iterator that may contain zero or more errors for the given value. For performance, you should only call Errors(V) if the Check(V) function returns false.

const C = TypeCompiler.Compile(Type.Object({
  x: Type.Number(),
  y: Type.Number(),
  z: Type.Number()
}))

const V = { } // invalid

if(!C.Check(V)) {
  for(const error of C.Errors(V)) {
    console.log(error)
  }
}

To inspect the generated validation code created by the compiler. You can call the Code() function on the TypeCheck<T> object.

const C = TypeCompiler.Compile(Type.String())

console.log(C.Code())
//
// outputs:
//
// return function check(value) {
//   return (
//     (typeof value === 'string')
//  )
// }

Contribute

TypeBox is open to community contribution, however please ensure you submit an open issue before submitting your pull request. The TypeBox project does preference open community discussion prior to accepting new features.