Gathering detailed insights and metrics for @sinclair/typebox
Gathering detailed insights and metrics for @sinclair/typebox
Gathering detailed insights and metrics for @sinclair/typebox
Gathering detailed insights and metrics for @sinclair/typebox
Json Schema Type Builder with Static Type Resolution for TypeScript
npm install @sinclair/typebox
Typescript
Module System
Node Version
NPM Version
100
Supply Chain
99.3
Quality
94.6
Maintenance
100
Vulnerability
100
License
TypeScript (99.8%)
JavaScript (0.2%)
Total Downloads
2,958,961,180
Last Day
6,149,054
Last Week
27,746,230
Last Month
121,636,773
Last Year
1,555,116,947
5,294 Stars
568 Commits
168 Forks
16 Watching
11 Branches
45 Contributors
Minified
Minified + Gzipped
Latest Version
0.34.15
Package Id
@sinclair/typebox@0.34.15
Unpacked Size
1.61 MB
Size
259.68 kB
File Count
1,053
NPM Version
10.9.2
Node Version
23.6.0
Publised On
30 Jan 2025
Cumulative downloads
Total Downloads
Last day
-3.7%
6,149,054
Compared to previous day
Last week
-13.6%
27,746,230
Compared to previous week
Last month
4.4%
121,636,773
Compared to previous month
Last year
37.7%
1,555,116,947
Compared to previous year
No dependencies detected.
1$ npm install @sinclair/typebox --save
1import { Type, type Static } from '@sinclair/typebox' 2 3const T = Type.Object({ // const T = { 4 x: Type.Number(), // type: 'object', 5 y: Type.Number(), // required: ['x', 'y', 'z'], 6 z: Type.Number() // properties: { 7}) // x: { type: 'number' }, 8 // y: { type: 'number' }, 9 // z: { type: 'number' } 10 // } 11 // } 12 13type T = Static<typeof T> // type T = { 14 // x: number, 15 // y: number, 16 // z: number 17 // }
TypeBox is a runtime type builder that creates in-memory Json Schema objects that infer as TypeScript types. The schematics produced by this library are designed to match the static type checking rules of the TypeScript compiler. TypeBox offers a unified type that can be statically checked by TypeScript and runtime asserted using standard Json Schema validation.
This library is designed to allow Json Schema to compose similar to how types compose within TypeScript's type system. It can be used as a simple tool to build up complex schematics or integrated into REST and RPC services to help validate data received over the wire.
License MIT
The following shows general usage.
1import { Type, type Static } from '@sinclair/typebox' 2 3//-------------------------------------------------------------------------------------------- 4// 5// Let's say you have the following type ... 6// 7//-------------------------------------------------------------------------------------------- 8 9type T = { 10 id: string, 11 name: string, 12 timestamp: number 13} 14 15//-------------------------------------------------------------------------------------------- 16// 17// ... you can express this type in the following way. 18// 19//-------------------------------------------------------------------------------------------- 20 21const T = Type.Object({ // const T = { 22 id: Type.String(), // type: 'object', 23 name: Type.String(), // properties: { 24 timestamp: Type.Integer() // id: { 25}) // type: 'string' 26 // }, 27 // name: { 28 // type: 'string' 29 // }, 30 // timestamp: { 31 // type: 'integer' 32 // } 33 // }, 34 // required: [ 35 // 'id', 36 // 'name', 37 // 'timestamp' 38 // ] 39 // } 40 41//-------------------------------------------------------------------------------------------- 42// 43// ... then infer back to the original static type this way. 44// 45//-------------------------------------------------------------------------------------------- 46 47type T = Static<typeof T> // type T = { 48 // id: string, 49 // name: string, 50 // timestamp: number 51 // } 52 53//-------------------------------------------------------------------------------------------- 54// 55// ... or use the type to parse JavaScript values. 56// 57//-------------------------------------------------------------------------------------------- 58 59import { Value } from '@sinclair/typebox/value' 60 61const R = Value.Parse(T, value) // const R: { 62 // id: string, 63 // name: string, 64 // timestamp: number 65 // }
TypeBox types are Json Schema fragments that compose into more complex types. Each fragment is structured such that any Json Schema compliant validator can runtime assert a value the same way TypeScript will statically assert a type. TypeBox offers a set of Json Types which are used to create Json Schema compliant schematics as well as a JavaScript type set used to create schematics for constructs native to JavaScript.
The following table lists the supported Json types. These types are fully compatible with the Json Schema Draft 7 specification.
1┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐ 2│ TypeBox │ TypeScript │ Json Schema │ 3│ │ │ │ 4├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 5│ const T = Type.Any() │ type T = any │ const T = { } │ 6│ │ │ │ 7├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 8│ const T = Type.Unknown() │ type T = unknown │ const T = { } │ 9│ │ │ │ 10├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 11│ const T = Type.String() │ type T = string │ const T = { │ 12│ │ │ type: 'string' │ 13│ │ │ } │ 14│ │ │ │ 15├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 16│ const T = Type.Number() │ type T = number │ const T = { │ 17│ │ │ type: 'number' │ 18│ │ │ } │ 19│ │ │ │ 20├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 21│ const T = Type.Integer() │ type T = number │ const T = { │ 22│ │ │ type: 'integer' │ 23│ │ │ } │ 24│ │ │ │ 25├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 26│ const T = Type.Boolean() │ type T = boolean │ const T = { │ 27│ │ │ type: 'boolean' │ 28│ │ │ } │ 29│ │ │ │ 30├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 31│ const T = Type.Null() │ type T = null │ const T = { │ 32│ │ │ type: 'null' │ 33│ │ │ } │ 34│ │ │ │ 35├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 36│ const T = Type.Literal(42) │ type T = 42 │ const T = { │ 37│ │ │ const: 42, │ 38│ │ │ type: 'number' │ 39│ │ │ } │ 40│ │ │ │ 41├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 42│ const T = Type.Array( │ type T = number[] │ const T = { │ 43│ Type.Number() │ │ type: 'array', │ 44│ ) │ │ items: { │ 45│ │ │ type: 'number' │ 46│ │ │ } │ 47│ │ │ } │ 48│ │ │ │ 49├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 50│ const T = Type.Object({ │ type T = { │ const T = { │ 51│ x: Type.Number(), │ x: number, │ type: 'object', │ 52│ y: Type.Number() │ y: number │ required: ['x', 'y'], │ 53│ }) │ } │ properties: { │ 54│ │ │ x: { │ 55│ │ │ type: 'number' │ 56│ │ │ }, │ 57│ │ │ y: { │ 58│ │ │ type: 'number' │ 59│ │ │ } │ 60│ │ │ } │ 61│ │ │ } │ 62│ │ │ │ 63├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 64│ const T = Type.Tuple([ │ type T = [number, number] │ const T = { │ 65│ Type.Number(), │ │ type: 'array', │ 66│ Type.Number() │ │ items: [{ │ 67│ ]) │ │ type: 'number' │ 68│ │ │ }, { │ 69│ │ │ type: 'number' │ 70│ │ │ }], │ 71│ │ │ additionalItems: false, │ 72│ │ │ minItems: 2, │ 73│ │ │ maxItems: 2 │ 74│ │ │ } │ 75│ │ │ │ 76│ │ │ │ 77├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 78│ enum Foo { │ enum Foo { │ const T = { │ 79│ A, │ A, │ anyOf: [{ │ 80│ B │ B │ type: 'number', │ 81│ } │ } │ const: 0 │ 82│ │ │ }, { │ 83│ const T = Type.Enum(Foo) │ type T = Foo │ type: 'number', │ 84│ │ │ const: 1 │ 85│ │ │ }] │ 86│ │ │ } │ 87│ │ │ │ 88├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 89│ const T = Type.Const({ │ type T = { │ const T = { │ 90│ x: 1, │ readonly x: 1, │ type: 'object', │ 91│ y: 2, │ readonly y: 2 │ required: ['x', 'y'], │ 92│ } as const) │ } │ properties: { │ 93│ │ │ x: { │ 94│ │ │ type: 'number', │ 95│ │ │ const: 1 │ 96│ │ │ }, │ 97│ │ │ y: { │ 98│ │ │ type: 'number', │ 99│ │ │ const: 2 │ 100│ │ │ } │ 101│ │ │ } │ 102│ │ │ } │ 103│ │ │ │ 104├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 105│ const T = Type.KeyOf( │ type T = keyof { │ const T = { │ 106│ Type.Object({ │ x: number, │ anyOf: [{ │ 107│ x: Type.Number(), │ y: number │ type: 'string', │ 108│ y: Type.Number() │ } │ const: 'x' │ 109│ }) │ │ }, { │ 110│ ) │ │ type: 'string', │ 111│ │ │ const: 'y' │ 112│ │ │ }] │ 113│ │ │ } │ 114│ │ │ │ 115├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 116│ const T = Type.Union([ │ type T = string | number │ const T = { │ 117│ Type.String(), │ │ anyOf: [{ │ 118│ Type.Number() │ │ type: 'string' │ 119│ ]) │ │ }, { │ 120│ │ │ type: 'number' │ 121│ │ │ }] │ 122│ │ │ } │ 123│ │ │ │ 124├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 125│ const T = Type.Intersect([ │ type T = { │ const T = { │ 126│ Type.Object({ │ x: number │ allOf: [{ │ 127│ x: Type.Number() │ } & { │ type: 'object', │ 128│ }), │ y: number │ required: ['x'], │ 129│ Type.Object({ │ } │ properties: { │ 130│ y: Type.Number() │ │ x: { │ 131│ }) │ │ type: 'number' │ 132│ ]) │ │ } │ 133│ │ │ } │ 134│ │ │ }, { │ 135│ │ │ type: 'object', | 136│ │ │ required: ['y'], │ 137│ │ │ properties: { │ 138│ │ │ y: { │ 139│ │ │ type: 'number' │ 140│ │ │ } │ 141│ │ │ } │ 142│ │ │ }] │ 143│ │ │ } │ 144│ │ │ │ 145├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 146│ const T = Type.Composite([ │ type T = { │ const T = { │ 147│ Type.Object({ │ x: number, │ type: 'object', │ 148│ x: Type.Number() │ y: number │ required: ['x', 'y'], │ 149│ }), │ } │ properties: { │ 150│ Type.Object({ │ │ x: { │ 151│ y: Type.Number() │ │ type: 'number' │ 152│ }) │ │ }, │ 153│ ]) │ │ y: { │ 154│ │ │ type: 'number' │ 155│ │ │ } │ 156│ │ │ } │ 157│ │ │ } │ 158│ │ │ │ 159├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 160│ const T = Type.Never() │ type T = never │ const T = { │ 161│ │ │ not: {} │ 162│ │ │ } │ 163│ │ │ │ 164├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 165│ const T = Type.Not( | type T = unknown │ const T = { │ 166│ Type.String() │ │ not: { │ 167│ ) │ │ type: 'string' │ 168│ │ │ } │ 169│ │ │ } │ 170├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 171│ const T = Type.Extends( │ type T = │ const T = { │ 172│ Type.String(), │ string extends number │ const: false, │ 173│ Type.Number(), │ ? true │ type: 'boolean' │ 174│ Type.Literal(true), │ : false │ } │ 175│ Type.Literal(false) │ │ │ 176│ ) │ │ │ 177│ │ │ │ 178├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 179│ const T = Type.Extract( │ type T = Extract< │ const T = { │ 180│ Type.Union([ │ string | number, │ type: 'string' │ 181│ Type.String(), │ string │ } │ 182│ Type.Number(), │ > │ │ 183│ ]), │ │ │ 184│ Type.String() │ │ │ 185│ ) │ │ │ 186│ │ │ │ 187├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 188│ const T = Type.Exclude( │ type T = Exclude< │ const T = { │ 189│ Type.Union([ │ string | number, │ type: 'number' │ 190│ Type.String(), │ string │ } │ 191│ Type.Number(), │ > │ │ 192│ ]), │ │ │ 193│ Type.String() │ │ │ 194│ ) │ │ │ 195│ │ │ │ 196├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 197│ const T = Type.Mapped( │ type T = { │ const T = { │ 198│ Type.Union([ │ [_ in 'x' | 'y'] : number │ type: 'object', │ 199│ Type.Literal('x'), │ } │ required: ['x', 'y'], │ 200│ Type.Literal('y') │ │ properties: { │ 201│ ]), │ │ x: { │ 202│ () => Type.Number() │ │ type: 'number' │ 203│ ) │ │ }, │ 204│ │ │ y: { │ 205│ │ │ type: 'number' │ 206│ │ │ } │ 207│ │ │ } │ 208│ │ │ } │ 209│ │ │ │ 210├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 211│ const U = Type.Union([ │ type U = 'open' | 'close' │ const T = { │ 212│ Type.Literal('open'), │ │ type: 'string', │ 213│ Type.Literal('close') │ type T = `on${U}` │ pattern: '^on(open|close)$' │ 214│ ]) │ │ } │ 215│ │ │ │ 216│ const T = Type │ │ │ 217│ .TemplateLiteral([ │ │ │ 218│ Type.Literal('on'), │ │ │ 219│ U │ │ │ 220│ ]) │ │ │ 221│ │ │ │ 222├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 223│ const T = Type.Record( │ type T = Record< │ const T = { │ 224│ Type.String(), │ string, │ type: 'object', │ 225│ Type.Number() │ number │ patternProperties: { │ 226│ ) │ > │ '^.*$': { │ 227│ │ │ type: 'number' │ 228│ │ │ } │ 229│ │ │ } │ 230│ │ │ } │ 231│ │ │ │ 232├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 233│ const T = Type.Partial( │ type T = Partial<{ │ const T = { │ 234│ Type.Object({ │ x: number, │ type: 'object', │ 235│ x: Type.Number(), │ y: number │ properties: { │ 236│ y: Type.Number() | }> │ x: { │ 237│ }) │ │ type: 'number' │ 238│ ) │ │ }, │ 239│ │ │ y: { │ 240│ │ │ type: 'number' │ 241│ │ │ } │ 242│ │ │ } │ 243│ │ │ } │ 244│ │ │ │ 245├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 246│ const T = Type.Required( │ type T = Required<{ │ const T = { │ 247│ Type.Object({ │ x?: number, │ type: 'object', │ 248│ x: Type.Optional( │ y?: number │ required: ['x', 'y'], │ 249│ Type.Number() | }> │ properties: { │ 250│ ), │ │ x: { │ 251│ y: Type.Optional( │ │ type: 'number' │ 252│ Type.Number() │ │ }, │ 253│ ) │ │ y: { │ 254│ }) │ │ type: 'number' │ 255│ ) │ │ } │ 256│ │ │ } │ 257│ │ │ } │ 258│ │ │ │ 259├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 260│ const T = Type.Pick( │ type T = Pick<{ │ const T = { │ 261│ Type.Object({ │ x: number, │ type: 'object', │ 262│ x: Type.Number(), │ y: number │ required: ['x'], │ 263│ y: Type.Number() │ }, 'x'> │ properties: { │ 264│ }), ['x'] | │ x: { │ 265│ ) │ │ type: 'number' │ 266│ │ │ } │ 267│ │ │ } │ 268│ │ │ } │ 269│ │ │ │ 270├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 271│ const T = Type.Omit( │ type T = Omit<{ │ const T = { │ 272│ Type.Object({ │ x: number, │ type: 'object', │ 273│ x: Type.Number(), │ y: number │ required: ['y'], │ 274│ y: Type.Number() │ }, 'x'> │ properties: { │ 275│ }), ['x'] | │ y: { │ 276│ ) │ │ type: 'number' │ 277│ │ │ } │ 278│ │ │ } │ 279│ │ │ } │ 280│ │ │ │ 281├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 282│ const T = Type.Index( │ type T = { │ const T = { │ 283│ Type.Object({ │ x: number, │ type: 'number' │ 284│ x: Type.Number(), │ y: string │ } │ 285│ y: Type.String() │ }['x'] │ │ 286│ }), ['x'] │ │ │ 287│ ) │ │ │ 288│ │ │ │ 289├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 290│ const A = Type.Tuple([ │ type A = [0, 1] │ const T = { │ 291│ Type.Literal(0), │ type B = [2, 3] │ type: 'array', │ 292│ Type.Literal(1) │ type T = [ │ items: [ │ 293│ ]) │ ...A, │ { const: 0 }, │ 294│ const B = Type.Tuple([ │ ...B │ { const: 1 }, │ 295| Type.Literal(2), │ ] │ { const: 2 }, │ 296| Type.Literal(3) │ │ { const: 3 } │ 297│ ]) │ │ ], │ 298│ const T = Type.Tuple([ │ │ additionalItems: false, │ 299| ...Type.Rest(A), │ │ minItems: 4, │ 300| ...Type.Rest(B) │ │ maxItems: 4 │ 301│ ]) │ │ } │ 302│ │ │ │ 303├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 304│ const T = Type.Uncapitalize( │ type T = Uncapitalize< │ const T = { │ 305│ Type.Literal('Hello') │ 'Hello' │ type: 'string', │ 306│ ) │ > │ const: 'hello' │ 307│ │ │ } │ 308│ │ │ │ 309├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 310│ const T = Type.Capitalize( │ type T = Capitalize< │ const T = { │ 311│ Type.Literal('hello') │ 'hello' │ type: 'string', │ 312│ ) │ > │ const: 'Hello' │ 313│ │ │ } │ 314│ │ │ │ 315├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 316│ const T = Type.Uppercase( │ type T = Uppercase< │ const T = { │ 317│ Type.Literal('hello') │ 'hello' │ type: 'string', │ 318│ ) │ > │ const: 'HELLO' │ 319│ │ │ } │ 320│ │ │ │ 321├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 322│ const T = Type.Lowercase( │ type T = Lowercase< │ const T = { │ 323│ Type.Literal('HELLO') │ 'HELLO' │ type: 'string', │ 324│ ) │ > │ const: 'hello' │ 325│ │ │ } │ 326│ │ │ │ 327├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 328│ const R = Type.Ref('T') │ type R = unknown │ const R = { $ref: 'T' } │ 329│ │ │ │ 330└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
TypeBox provides an extended type set that can be used to create schematics for common JavaScript constructs. These types can not be used with any standard Json Schema validator; but can be used to frame schematics for interfaces that may receive Json validated data. JavaScript types are prefixed with the [JavaScript]
jsdoc comment for convenience. The following table lists the supported types.
1┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐ 2│ TypeBox │ TypeScript │ Extended Schema │ 3│ │ │ │ 4├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 5│ const T = Type.Constructor([ │ type T = new ( │ const T = { │ 6│ Type.String(), │ arg0: string, │ type: 'Constructor', │ 7│ Type.Number() │ arg0: number │ parameters: [{ │ 8│ ], Type.Boolean()) │ ) => boolean │ type: 'string' │ 9│ │ │ }, { │ 10│ │ │ type: 'number' │ 11│ │ │ }], │ 12│ │ │ returns: { │ 13│ │ │ type: 'boolean' │ 14│ │ │ } │ 15│ │ │ } │ 16│ │ │ │ 17├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 18│ const T = Type.Function([ │ type T = ( │ const T = { │ 19| Type.String(), │ arg0: string, │ type: 'Function', │ 20│ Type.Number() │ arg1: number │ parameters: [{ │ 21│ ], Type.Boolean()) │ ) => boolean │ type: 'string' │ 22│ │ │ }, { │ 23│ │ │ type: 'number' │ 24│ │ │ }], │ 25│ │ │ returns: { │ 26│ │ │ type: 'boolean' │ 27│ │ │ } │ 28│ │ │ } │ 29│ │ │ │ 30├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 31│ const T = Type.Promise( │ type T = Promise<string> │ const T = { │ 32│ Type.String() │ │ type: 'Promise', │ 33│ ) │ │ item: { │ 34│ │ │ type: 'string' │ 35│ │ │ } │ 36│ │ │ } │ 37│ │ │ │ 38├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 39│ const T = │ type T = │ const T = { │ 40│ Type.AsyncIterator( │ AsyncIterableIterator< │ type: 'AsyncIterator', │ 41│ Type.String() │ string │ items: { │ 42│ ) │ > │ type: 'string' │ 43│ │ │ } │ 44│ │ │ } │ 45│ │ │ │ 46├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 47│ const T = Type.Iterator( │ type T = │ const T = { │ 48│ Type.String() │ IterableIterator<string> │ type: 'Iterator', │ 49│ ) │ │ items: { │ 50│ │ │ type: 'string' │ 51│ │ │ } │ 52│ │ │ } │ 53│ │ │ │ 54├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 55│ const T = Type.RegExp(/abc/i) │ type T = string │ const T = { │ 56│ │ │ type: 'RegExp' │ 57│ │ │ source: 'abc' │ 58│ │ │ flags: 'i' │ 59│ │ │ } │ 60│ │ │ │ 61├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 62│ const T = Type.Uint8Array() │ type T = Uint8Array │ const T = { │ 63│ │ │ type: 'Uint8Array' │ 64│ │ │ } │ 65│ │ │ │ 66├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 67│ const T = Type.Date() │ type T = Date │ const T = { │ 68│ │ │ type: 'Date' │ 69│ │ │ } │ 70│ │ │ │ 71├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 72│ const T = Type.Undefined() │ type T = undefined │ const T = { │ 73│ │ │ type: 'undefined' │ 74│ │ │ } │ 75│ │ │ │ 76├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 77│ const T = Type.Symbol() │ type T = symbol │ const T = { │ 78│ │ │ type: 'symbol' │ 79│ │ │ } │ 80│ │ │ │ 81├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 82│ const T = Type.BigInt() │ type T = bigint │ const T = { │ 83│ │ │ type: 'bigint' │ 84│ │ │ } │ 85│ │ │ │ 86├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 87│ const T = Type.Void() │ type T = void │ const T = { │ 88│ │ │ type: 'void' │ 89│ │ │ } │ 90│ │ │ │ 91└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
Import the Type namespace to bring in the full TypeBox type system. This is recommended for most users.
1import { Type, type Static } from '@sinclair/typebox'
You can also selectively import types. This enables modern bundlers to tree shake for unused types.
1import { Object, Number, String, Boolean, type Static } from '@sinclair/typebox'
You can pass Json Schema options on the last argument of any given type. Option hints specific to each type are provided for convenience.
1// String must be an email 2const T = Type.String({ // const T = { 3 format: 'email' // type: 'string', 4}) // format: 'email' 5 // } 6 7// Number must be a multiple of 2 8const T = Type.Number({ // const T = { 9 multipleOf: 2 // type: 'number', 10}) // multipleOf: 2 11 // } 12 13// Array must have at least 5 integer values 14const T = Type.Array(Type.Integer(), { // const T = { 15 minItems: 5 // type: 'array', 16}) // minItems: 5, 17 // items: { 18 // type: 'integer' 19 // } 20 // }
Object properties can be modified with Readonly and Optional. The following table shows how these modifiers map between TypeScript and Json Schema.
1┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐ 2│ TypeBox │ TypeScript │ Json Schema │ 3│ │ │ │ 4├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 5│ const T = Type.Object({ │ type T = { │ const T = { │ 6│ name: Type.ReadonlyOptional( │ readonly name?: string │ type: 'object', │ 7│ Type.String() │ } │ properties: { │ 8│ ) │ │ name: { │ 9│ }) │ │ type: 'string' │ 10│ │ │ } │ 11│ │ │ } │ 12│ │ │ } │ 13│ │ │ │ 14├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 15│ const T = Type.Object({ │ type T = { │ const T = { │ 16│ name: Type.Readonly( │ readonly name: string │ type: 'object', │ 17│ Type.String() │ } │ properties: { │ 18│ ) │ │ name: { │ 19│ }) │ │ type: 'string' │ 20│ │ │ } │ 21│ │ │ }, │ 22│ │ │ required: ['name'] │ 23│ │ │ } │ 24│ │ │ │ 25├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ 26│ const T = Type.Object({ │ type T = { │ const T = { │ 27│ name: Type.Optional( │ name?: string │ type: 'object', │ 28│ Type.String() │ } │ properties: { │ 29│ ) │ │ name: { │ 30│ }) │ │ type: 'string' │ 31│ │ │ } │ 32│ │ │ } │ 33│ │ │ } │ 34│ │ │ │ 35└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
Generic types can be created with functions. TypeBox types extend the TSchema interface so you should constrain parameters to this type. The following creates a generic Vector type.
1import { Type, type Static, type TSchema } from '@sinclair/typebox' 2 3const Vector = <T extends TSchema>(T: T) => 4 Type.Object({ // type Vector<T> = { 5 x: T, // x: T, 6 y: T, // y: T, 7 z: T // z: T 8 }) // } 9 10const NumberVector = Vector(Type.Number()) // type NumberVector = Vector<number>
Generic types are often used to create aliases for complex types. The following creates a Nullable generic type.
1const Nullable = <T extends TSchema>(schema: T) => Type.Union([schema, Type.Null()]) 2 3const T = Nullable(Type.String()) // const T = { 4 // anyOf: [ 5 // { type: 'string' }, 6 // { type: 'null' } 7 // ] 8 // } 9 10type T = Static<typeof T> // type T = string | null
Use the Recursive function to create a singular recursive type.
1const Node = Type.Recursive(Self => Type.Object({ // const Node = { 2 id: Type.String(), // $id: 'Node', 3 nodes: Type.Array(Self) // type: 'object', 4}), { $id: 'Node' }) // properties: { 5 // id: { 6 // type: 'string' 7 // }, 8 // nodes: { 9 // type: 'array', 10 // items: { 11 // $ref: 'Node' 12 // } 13 // } 14 // }, 15 // required: [ 16 // 'id', 17 // 'nodes' 18 // ] 19 // } 20 21type Node = Static<typeof Node> // type Node = { 22 // id: string 23 // nodes: Node[] 24 // } 25 26function test(node: Node) { 27 const id = node.nodes[0].nodes[0].id // id is string 28}
Module types are containers for a set of referential types. Modules act as namespaces, enabling types to reference one another via string identifiers. Modules support both singular and mutually recursive references, as well as deferred dereferencing for computed types such as Partial. Types imported from a module are expressed using the Json Schema $defs
keyword.
1const Module = Type.Module({ 2 PartialUser: Type.Partial(Type.Ref('User')), // TComputed<'Partial', [TRef<'User'>]> 3 4 User: Type.Object({ // TObject<{ 5 id: Type.String(), // user: TString, 6 name: Type.String(), // name: TString, 7 email: Type.String() // email: TString 8 }), // }> 9}) 10const User = Module.Import('User') // const User: TImport<{...}, 'User'> 11 12type User = Static<typeof User> // type User = { 13 // id: string, 14 // name: string, 15 // email: string 16 // } 17 18const PartialUser = Module.Import('PartialUser') // const PartialUser: TImport<{...}, 'PartialUser'> 19 20type PartialUser = Static<typeof PartialUser> // type PartialUser = { 21 // id?: string, 22 // name?: string, 23 // email?: string 24 // }
TypeBox supports template literal types with the TemplateLiteral function. This type can be created using a syntax similar to the TypeScript template literal syntax or composed from exterior types. TypeBox encodes template literals as regular expressions which enables the template to be checked by Json Schema validators. This type also supports regular expression parsing that enables template patterns to be used for generative types. The following shows both TypeScript and TypeBox usage.
1// TypeScript 2 3type K = `prop${'A'|'B'|'C'}` // type T = 'propA' | 'propB' | 'propC' 4 5type R = Record<K, string> // type R = { 6 // propA: string 7 // propB: string 8 // propC: string 9 // } 10 11// TypeBox 12 13const K = Type.TemplateLiteral('prop${A|B|C}') // const K: TTemplateLiteral<[ 14 // TLiteral<'prop'>, 15 // TUnion<[ 16 // TLiteral<'A'>, 17 // TLiteral<'B'>, 18 // TLiteral<'C'>, 19 // ]> 20 // ]> 21 22const R = Type.Record(K, Type.String()) // const R: TObject<{ 23 // propA: TString, 24 // propB: TString, 25 // propC: TString, 26 // }>
TypeBox supports indexed access types with the Index function. This function enables uniform access to interior property and element types without having to extract them from the underlying schema representation. Index types are supported for Object, Array, Tuple, Union and Intersect types.
1const T = Type.Object({ // type T = { 2 x: Type.Number(), // x: number, 3 y: Type.String(), // y: string, 4 z: Type.Boolean() // z: boolean 5}) // } 6 7const A = Type.Index(T, ['x']) // type A = T['x'] 8 // 9 // ... evaluated as 10 // 11 // const A: TNumber 12 13const B = Type.Index(T, ['x', 'y']) // type B = T['x' | 'y'] 14 // 15 // ... evaluated as 16 // 17 // const B: TUnion<[ 18 // TNumber, 19 // TString, 20 // ]> 21 22const C = Type.Index(T, Type.KeyOf(T)) // type C = T[keyof T] 23 // 24 // ... evaluated as 25 // 26 // const C: TUnion<[ 27 // TNumber, 28 // TString, 29 // TBoolean 30 // ]>
TypeBox supports mapped types with the Mapped function. This function ac
No vulnerabilities found.
Reason
30 commit(s) and 25 issue activity found in the last 90 days -- score normalized to 10
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
0 existing vulnerabilities detected
Reason
license file detected
Details
Reason
Found 2/30 approved changesets -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
project is not fuzzed
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2025-01-27
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More