Skip to main content
Deno 2 is finally here πŸŽ‰οΈ
Learn more

TypeBox

JSON Schema Type Builder with Static Type Resolution for TypeScript



npm version Downloads 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 enables one to create unified types that can be statically checked by TypeScript and 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.

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               β”‚   parameters: [{               β”‚
β”‚ ], Type.Boolean())             β”‚ ) => boolean                β”‚     type: 'string'             β”‚
β”‚                                β”‚                             β”‚   }, {                         β”‚
β”‚                                β”‚                             β”‚     type: 'number'             β”‚
β”‚                                β”‚                             β”‚   }],                          β”‚
β”‚                                β”‚                             β”‚   return: {                    β”‚
β”‚                                β”‚                             β”‚     type: 'boolean'            β”‚
β”‚                                β”‚                             β”‚   }                            β”‚
β”‚                                β”‚                             β”‚ }                              β”‚
β”‚                                β”‚                             β”‚                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ const T = Type.Function([      β”‚ type T = (                  β”‚ const T = {                    β”‚
|   Type.String(),               β”‚  arg0: string,              β”‚   type : 'function',           β”‚
β”‚   Type.Number()                β”‚  arg1: number               β”‚   parameters: [{               β”‚
β”‚ ], Type.Boolean())             β”‚ ) => boolean                β”‚     type: 'string'             β”‚
β”‚                                β”‚                             β”‚   }, {                         β”‚
β”‚                                β”‚                             β”‚     type: 'number'             β”‚
β”‚                                β”‚                             β”‚   }],                          β”‚
β”‚                                β”‚                             β”‚   return: {                    β”‚
β”‚                                β”‚                             β”‚     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

Use Type.Ref(...) to create referenced types. 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

Use Type.Recursive(...) to create recursive types.

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: Node[]
                                                     // }

function test(node: Node) {
  const id = node.nodes[0].nodes[0].nodes[0]         // id is string
                 .nodes[0].nodes[0].nodes[0]
                 .nodes[0].nodes[0].nodes[0]
                 .id
}

Generic Types

Use functions to create generic types. 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

Use Type.Unsafe(...) to create custom schemas with user defined inference rules.

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 to create schemas for validators that require specific schema representations. An example of this would be OpenAPI’s nullable and enum schemas which are not provided by TypeBox. The following demonstrates using Type.Unsafe(...) to create these types.

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

//--------------------------------------------------------------------------------------------
//
// StringEnum<string[]>
//
//--------------------------------------------------------------------------------------------

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

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

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

Conditional Types

Use Conditional.Extends(...) to create conditional mapped types.

import { Conditional } from '@sinclair/typebox/conditional'

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

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ TypeBox                        β”‚ TypeScript                  β”‚ JSON Schema                    β”‚
β”‚                                β”‚                             β”‚                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ const T = Conditional.Extends( β”‚ type T =                    β”‚ const T = {                    β”‚
β”‚   Type.String(),               β”‚  string extends number      β”‚   const: false,                β”‚
β”‚   Type.Number(),               β”‚  true : false               β”‚   type: 'boolean'              β”‚
β”‚   Type.Literal(true),          β”‚                             β”‚ }                              β”‚
β”‚   Type.Literal(false)          β”‚                             β”‚                                β”‚
β”‚ )                              β”‚                             β”‚                                β”‚
β”‚                                β”‚                             β”‚                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ const T = Conditional.Extract( β”‚ type T = Extract<           β”‚ const T = {                    β”‚
β”‚   Type.Union([                 β”‚   'a' | 'b' | 'c',          β”‚   anyOf: [{                    β”‚
β”‚     Type.Literal('a'),         β”‚   'a' | 'f'                 β”‚     const: 'a'                 β”‚
β”‚     Type.Literal('b'),         β”‚ >                           β”‚     type: 'string'             β”‚
β”‚     Type.Literal('c')          β”‚                             β”‚   }]                           β”‚
β”‚   ]),                          β”‚                             β”‚ }                              β”‚
β”‚   Type.Union([                 β”‚                             β”‚                                β”‚
β”‚     Type.Literal('a'),         β”‚                             β”‚                                β”‚
β”‚     Type.Literal('f')          β”‚                             β”‚                                β”‚
β”‚   ])                           β”‚                             β”‚                                β”‚
β”‚ )                              β”‚                             β”‚                                β”‚
β”‚                                β”‚                             β”‚                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ const T = Conditional.Exclude( β”‚ type T = Exclude<           β”‚ const T = {                    β”‚
β”‚   Type.Union([                 β”‚   'a' | 'b' | 'c',          β”‚   anyOf: [{                    β”‚
β”‚     Type.Literal('a'),         β”‚   'a'                       β”‚     const: 'b',                β”‚
β”‚     Type.Literal('b'),         β”‚ >                           β”‚     type: 'string'             β”‚
β”‚     Type.Literal('c')          β”‚                             β”‚   }, {                         β”‚
β”‚   ]),                          β”‚                             β”‚     const: 'c',                β”‚
β”‚   Type.Union([                 β”‚                             β”‚     type: 'string'             β”‚
β”‚     Type.Literal('a')          β”‚                             β”‚   }]                           β”‚
β”‚   ])                           β”‚                             β”‚ }                              β”‚
β”‚ )                              β”‚                             β”‚                                β”‚
β”‚                                β”‚                             β”‚                                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Values

Use Value.Create(...) to generate values from types.

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

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

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

Use Value.Cast(...) to cast a value into a given type.

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

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

const A = Value.Cast(T, null)                          // const A = { x: 0, y: 0 }

const B = Value.Cast(T, { x: 1 })                      // const B = { x: 1, y: 0 }

const C = Value.Cast(T, { x: 1, y: 2, z: 3 })          // const C = { x: 1, y: 2 }

Guards

Use a TypeGuard to test if a value meets a TypeBox type specification. Guards can be helpful when reflecting types.

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

const T = Type.String()

if(TypeGuard.TString(T)) {
    
  // T is TString
}

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 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 T = Type.Object({
  x: Type.Number(),
  y: Type.Number(),
  z: Type.Number()
})

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

const R = ajv.validate(T, { x: 1, y: 2, z: 3 })      // const R = true

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

Compiler

TypeBox provides an optional high performance runtime type checker that can be used in applications that require extremely fast validation. This type checker is optimized for TypeBox types only whose schematics are known in advance. If defining custom schemas with Type.Unsafe<T> please consider Ajv.

The following demonstrates its use.

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

const C = TypeCompiler.Compile(Type.Object({         // const C: TypeCheck<TObject<{
  x: Type.Number(),                                  //     x: TNumber;
  y: Type.Number(),                                  //     y: TNumber;
  z: Type.Number()                                   //     z: TNumber;
}))                                                  // }>>

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

Validation errors can be read with the Errors(...) function.

const C = TypeCompiler.Compile(Type.Object({         // const C: TypeCheck<TObject<{
  x: Type.Number(),                                  //     x: TNumber;
  y: Type.Number(),                                  //     y: TNumber;
  z: Type.Number()                                   //     z: TNumber;
}))                                                  // }>>

const value = { }

const errors = [...C.Errors(value)]                  // const errors = [{
                                                     //   type: 14,
                                                     //   schema: { type: 'number' },
                                                     //   path: '/x',
                                                     //   value: undefined,
                                                     //   message: 'Expected number'
                                                     // }, {
                                                     //   type: 14,
                                                     //   schema: { type: 'number' },
                                                     //   path: '/y',
                                                     //   value: undefined,
                                                     //   message: 'Expected number'
                                                     // }, {
                                                     //   type: 14,
                                                     //   schema: { type: 'number' },
                                                     //   path: '/z',
                                                     //   value: undefined,
                                                     //   message: 'Expected number'
                                                     // }]

Compiled routines can be inspected with the .Code() function.

const C = TypeCompiler.Compile(Type.String())        // const C: TypeCheck<TString>

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

Benchmark

This project maintains a set of benchmarks that measure Ajv and TypeCompiler compilation and validation performance. These benchmarks can be run locally by cloning this repository and running npm run benchmark. The results below show for Ajv version 8.11.0.

For additional comparative benchmarks, please refer to typescript-runtime-type-benchmarks.

Compile

This benchmark measures compilation performance for varying types. You can review this benchmark here.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     (index)      β”‚ Iterations β”‚     Ajv      β”‚ TypeCompiler β”‚ Performance  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚           Number β”‚    2000    β”‚ '    382 ms' β”‚ '      8 ms' β”‚ '   47.75 x' β”‚
β”‚           String β”‚    2000    β”‚ '    305 ms' β”‚ '      7 ms' β”‚ '   43.57 x' β”‚
β”‚          Boolean β”‚    2000    β”‚ '    305 ms' β”‚ '      5 ms' β”‚ '   61.00 x' β”‚
β”‚             Null β”‚    2000    β”‚ '    253 ms' β”‚ '      5 ms' β”‚ '   50.60 x' β”‚
β”‚            RegEx β”‚    2000    β”‚ '    475 ms' β”‚ '     10 ms' β”‚ '   47.50 x' β”‚
β”‚          ObjectA β”‚    2000    β”‚ '   2812 ms' β”‚ '     44 ms' β”‚ '   63.91 x' β”‚
β”‚          ObjectB β”‚    2000    β”‚ '   3045 ms' β”‚ '     34 ms' β”‚ '   89.56 x' β”‚
β”‚            Tuple β”‚    2000    β”‚ '   1324 ms' β”‚ '     19 ms' β”‚ '   69.68 x' β”‚
β”‚            Union β”‚    2000    β”‚ '   1347 ms' β”‚ '     26 ms' β”‚ '   51.81 x' β”‚
β”‚          Vector4 β”‚    2000    β”‚ '   1635 ms' β”‚ '     18 ms' β”‚ '   90.83 x' β”‚
β”‚          Matrix4 β”‚    2000    β”‚ '    928 ms' β”‚ '     10 ms' β”‚ '   92.80 x' β”‚
β”‚   Literal_String β”‚    2000    β”‚ '    349 ms' β”‚ '      5 ms' β”‚ '   69.80 x' β”‚
β”‚   Literal_Number β”‚    2000    β”‚ '    379 ms' β”‚ '      5 ms' β”‚ '   75.80 x' β”‚
β”‚  Literal_Boolean β”‚    2000    β”‚ '    376 ms' β”‚ '      6 ms' β”‚ '   62.67 x' β”‚
β”‚     Array_Number β”‚    2000    β”‚ '    733 ms' β”‚ '     10 ms' β”‚ '   73.30 x' β”‚
β”‚     Array_String β”‚    2000    β”‚ '    766 ms' β”‚ '      8 ms' β”‚ '   95.75 x' β”‚
β”‚    Array_Boolean β”‚    2000    β”‚ '    860 ms' β”‚ '     11 ms' β”‚ '   78.18 x' β”‚
β”‚    Array_ObjectA β”‚    2000    β”‚ '   3668 ms' β”‚ '     42 ms' β”‚ '   87.33 x' β”‚
β”‚    Array_ObjectB β”‚    2000    β”‚ '   3809 ms' β”‚ '     41 ms' β”‚ '   92.90 x' β”‚
β”‚      Array_Tuple β”‚    2000    β”‚ '   2219 ms' β”‚ '     17 ms' β”‚ '  130.53 x' β”‚
β”‚      Array_Union β”‚    2000    β”‚ '   1709 ms' β”‚ '     26 ms' β”‚ '   65.73 x' β”‚
β”‚    Array_Vector4 β”‚    2000    β”‚ '   2301 ms' β”‚ '     18 ms' β”‚ '  127.83 x' β”‚
β”‚    Array_Matrix4 β”‚    2000    β”‚ '   1594 ms' β”‚ '     12 ms' β”‚ '  132.83 x' β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Validate

This benchmark measures validation performance for varying types. You can review this benchmark here.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     (index)      β”‚ Iterations β”‚     Ajv      β”‚ TypeCompiler β”‚ Performance  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚           Number β”‚  4000000   β”‚ '     18 ms' β”‚ '     16 ms' β”‚ '    1.13 x' β”‚
β”‚           String β”‚  4000000   β”‚ '     74 ms' β”‚ '     43 ms' β”‚ '    1.72 x' β”‚
β”‚          Boolean β”‚  4000000   β”‚ '     71 ms' β”‚ '     37 ms' β”‚ '    1.92 x' β”‚
β”‚             Null β”‚  4000000   β”‚ '     70 ms' β”‚ '     37 ms' β”‚ '    1.89 x' β”‚
β”‚            RegEx β”‚  4000000   β”‚ '    175 ms' β”‚ '    153 ms' β”‚ '    1.14 x' β”‚
β”‚          ObjectA β”‚  4000000   β”‚ '    124 ms' β”‚ '     87 ms' β”‚ '    1.43 x' β”‚
β”‚          ObjectB β”‚  4000000   β”‚ '    215 ms' β”‚ '    143 ms' β”‚ '    1.50 x' β”‚
β”‚            Tuple β”‚  4000000   β”‚ '    101 ms' β”‚ '     51 ms' β”‚ '    1.98 x' β”‚
β”‚            Union β”‚  4000000   β”‚ '    108 ms' β”‚ '     51 ms' β”‚ '    2.12 x' β”‚
β”‚        Recursive β”‚  4000000   β”‚ '   1647 ms' β”‚ '    626 ms' β”‚ '    2.63 x' β”‚
β”‚          Vector4 β”‚  4000000   β”‚ '     83 ms' β”‚ '     41 ms' β”‚ '    2.02 x' β”‚
β”‚          Matrix4 β”‚  4000000   β”‚ '    154 ms' β”‚ '    105 ms' β”‚ '    1.47 x' β”‚
β”‚   Literal_String β”‚  4000000   β”‚ '    101 ms' β”‚ '     37 ms' β”‚ '    2.73 x' β”‚
β”‚   Literal_Number β”‚  4000000   β”‚ '     69 ms' β”‚ '     35 ms' β”‚ '    1.97 x' β”‚
β”‚  Literal_Boolean β”‚  4000000   β”‚ '     71 ms' β”‚ '     35 ms' β”‚ '    2.03 x' β”‚
β”‚     Array_Number β”‚  4000000   β”‚ '    117 ms' β”‚ '     61 ms' β”‚ '    1.92 x' β”‚
β”‚     Array_String β”‚  4000000   β”‚ '    116 ms' β”‚ '     73 ms' β”‚ '    1.59 x' β”‚
β”‚    Array_Boolean β”‚  4000000   β”‚ '    129 ms' β”‚ '     89 ms' β”‚ '    1.45 x' β”‚
β”‚    Array_ObjectA β”‚  4000000   β”‚ '  10582 ms' β”‚ '   6854 ms' β”‚ '    1.54 x' β”‚
β”‚    Array_ObjectB β”‚  4000000   β”‚ '  11539 ms' β”‚ '   8224 ms' β”‚ '    1.40 x' β”‚
β”‚      Array_Tuple β”‚  4000000   β”‚ '    362 ms' β”‚ '    282 ms' β”‚ '    1.28 x' β”‚
β”‚      Array_Union β”‚  4000000   β”‚ '    950 ms' β”‚ '    355 ms' β”‚ '    2.68 x' β”‚
β”‚  Array_Recursive β”‚  4000000   β”‚ '  28047 ms' β”‚ '   9567 ms' β”‚ '    2.93 x' β”‚
β”‚    Array_Vector4 β”‚  4000000   β”‚ '    372 ms' β”‚ '    200 ms' β”‚ '    1.86 x' β”‚
β”‚    Array_Matrix4 β”‚  4000000   β”‚ '   1521 ms' β”‚ '   1244 ms' β”‚ '    1.22 x' β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Contribute

TypeBox is open to community contribution. Please ensure you submit an open issue before submitting your pull request. The TypeBox project preferences open community discussion prior to accepting new features.