@sinclair/typebox 0.30.4 → 0.31.0-dev-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/readme.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  <h1>TypeBox</h1>
4
4
 
5
- <p>JSON Schema Type Builder with Static Type Resolution for TypeScript</p>
5
+ <p>Json Schema Type Builder with Static Type Resolution for TypeScript</p>
6
6
 
7
7
  <img src="https://github.com/sinclairzx81/typebox/blob/master/typebox.png?raw=true" />
8
8
 
@@ -25,37 +25,32 @@
25
25
  $ npm install @sinclair/typebox --save
26
26
  ```
27
27
 
28
- #### Deno
29
- ```typescript
30
- import { Static, Type } from 'npm:@sinclair/typebox'
31
- ```
32
-
33
- #### Esm
28
+ #### Esm + Deno
34
29
 
35
30
  ```typescript
36
- import { Static, Type } from 'https://esm.sh/@sinclair/typebox'
31
+ import { Type, Static } from 'https://esm.sh/@sinclair/typebox'
37
32
  ```
38
33
 
39
34
  ## Example
40
35
 
41
36
  ```typescript
42
- import { Static, Type } from '@sinclair/typebox'
43
-
44
- const T = Type.Object({ // const T = {
45
- x: Type.Number(), // type: 'object',
46
- y: Type.Number(), // required: ['x', 'y', 'z'],
47
- z: Type.Number() // properties: {
48
- }) // x: { type: 'number' },
49
- // y: { type: 'number' },
50
- // z: { type: 'number' }
51
- // }
52
- // }
53
-
54
- type T = Static<typeof T> // type T = {
55
- // x: number,
56
- // y: number,
57
- // z: number
58
- // }
37
+ import { Type, Static } from '@sinclair/typebox'
38
+
39
+ const T = Type.Object({ // const T = {
40
+ x: Type.Number(), // type: 'object',
41
+ y: Type.Number(), // required: ['x', 'y', 'z'],
42
+ z: Type.Number() // properties: {
43
+ }) // x: { type: 'number' },
44
+ // y: { type: 'number' },
45
+ // z: { type: 'number' }
46
+ // }
47
+ // }
48
+
49
+ type T = Static<typeof T> // type T = {
50
+ // x: number,
51
+ // y: number,
52
+ // z: number
53
+ // }
59
54
  ```
60
55
 
61
56
 
@@ -63,9 +58,11 @@ type T = Static<typeof T> // type T = {
63
58
 
64
59
  ## Overview
65
60
 
66
- TypeBox is a runtime type builder 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 assertion rules of the TypeScript language. TypeBox allows one to create a unified type that can be statically checked by TypeScript and runtime asserted using standard JSON Schema validation.
61
+ TypeBox is a runtime type builder that creates Json Schema objects that infer as TypeScript types. The schemas produced by this library are designed specifically to match the static type checking assertion rules of the TypeScript programming language. TypeBox offers a unified type that can be statically checked by TypeScript and runtime asserted using standard Json Schema validation.
67
62
 
68
- This library is designed to enable JSON schema to compose with the same flexibility as TypeScript's type system. It can be used as a simple tool to build up complex schemas or integrated into REST or RPC services to help validate data received over the wire.
63
+ TypeBox is built to be a runtime type system that is based on industry standard specifications for use in distributed systems. It has serializable and publishable types as standard, a fully extensible type system able to support multiple specifications, includes an extremely high performance runtime validator, offers various utilities for working with dynamic data and has detailed and customizable structured error reporting.
64
+
65
+ TypeBox can be used as a simple tool to build up complex schemas or integrated into applications and frameworks to validate data received over the wire.
69
66
 
70
67
  License MIT
71
68
 
@@ -74,19 +71,19 @@ License MIT
74
71
  - [Overview](#overview)
75
72
  - [Usage](#usage)
76
73
  - [Types](#types)
77
- - [Standard](#types-standard)
78
- - [Extended](#types-extended)
74
+ - [Json](#types-json)
75
+ - [JavaScript](#types-javascript)
79
76
  - [Options](#types-options)
80
77
  - [Properties](#types-properties)
81
78
  - [Generics](#types-generics)
82
79
  - [References](#types-references)
83
80
  - [Recursive](#types-recursive)
84
81
  - [Conditional](#types-conditional)
85
- - [Template Literal](#types-template-literal)
82
+ - [Template Literal](#types-templateliteral)
86
83
  - [Indexed](#types-indexed)
87
- - [Negated](#types-negated)
88
- - [Intrinsic](#types-intrinsic)
89
84
  - [Rest](#types-rest)
85
+ - [Transform](#types-transform)
86
+ - [Intrinsic](#types-intrinsic)
90
87
  - [Guards](#types-guards)
91
88
  - [Unsafe](#types-unsafe)
92
89
  - [Strict](#types-strict)
@@ -96,6 +93,8 @@ License MIT
96
93
  - [Check](#values-check)
97
94
  - [Convert](#values-convert)
98
95
  - [Cast](#values-cast)
96
+ - [Decode](#values-decode)
97
+ - [Encode](#values-decode)
99
98
  - [Equal](#values-equal)
100
99
  - [Hash](#values-hash)
101
100
  - [Diff](#values-diff)
@@ -103,14 +102,19 @@ License MIT
103
102
  - [Errors](#values-errors)
104
103
  - [Mutate](#values-mutate)
105
104
  - [Pointer](#values-pointer)
105
+ - [TypeRegistry](#typeregistry)
106
+ - [Type](#typeregistry-type)
107
+ - [Format](#typeregistry-format)
106
108
  - [TypeCheck](#typecheck)
107
109
  - [Ajv](#typecheck-ajv)
108
110
  - [TypeCompiler](#typecheck-typecompiler)
109
111
  - [TypeSystem](#typesystem)
110
112
  - [Types](#typesystem-types)
111
113
  - [Formats](#typesystem-formats)
114
+ - [Errors](#typesystem-errors)
112
115
  - [Policies](#typesystem-policies)
113
116
  - [Workbench](#workbench)
117
+ - [Codegen](#codegen)
114
118
  - [Ecosystem](#ecosystem)
115
119
  - [Benchmark](#benchmark)
116
120
  - [Compile](#benchmark-compile)
@@ -125,7 +129,7 @@ License MIT
125
129
  The following shows general usage.
126
130
 
127
131
  ```typescript
128
- import { Static, Type } from '@sinclair/typebox'
132
+ import { Type, Static } from '@sinclair/typebox'
129
133
 
130
134
  //--------------------------------------------------------------------------------------------
131
135
  //
@@ -145,25 +149,25 @@ type T = {
145
149
  //
146
150
  //--------------------------------------------------------------------------------------------
147
151
 
148
- const T = Type.Object({ // const T = {
149
- id: Type.String(), // type: 'object',
150
- name: Type.String(), // properties: {
151
- timestamp: Type.Integer() // id: {
152
- }) // type: 'string'
153
- // },
154
- // name: {
155
- // type: 'string'
156
- // },
157
- // timestamp: {
158
- // type: 'integer'
159
- // }
160
- // },
161
- // required: [
162
- // 'id',
163
- // 'name',
164
- // 'timestamp'
165
- // ]
166
- // }
152
+ const T = Type.Object({ // const T = {
153
+ id: Type.String(), // type: 'object',
154
+ name: Type.String(), // properties: {
155
+ timestamp: Type.Integer() // id: {
156
+ }) // type: 'string'
157
+ // },
158
+ // name: {
159
+ // type: 'string'
160
+ // },
161
+ // timestamp: {
162
+ // type: 'integer'
163
+ // }
164
+ // },
165
+ // required: [
166
+ // 'id',
167
+ // 'name',
168
+ // 'timestamp'
169
+ // ]
170
+ // }
167
171
 
168
172
  //--------------------------------------------------------------------------------------------
169
173
  //
@@ -171,23 +175,23 @@ const T = Type.Object({ // const T = {
171
175
  //
172
176
  //--------------------------------------------------------------------------------------------
173
177
 
174
- type T = Static<typeof T> // type T = {
175
- // id: string,
176
- // name: string,
177
- // timestamp: number
178
- // }
178
+ type T = Static<typeof T> // type T = {
179
+ // id: string,
180
+ // name: string,
181
+ // timestamp: number
182
+ // }
179
183
 
180
184
  //--------------------------------------------------------------------------------------------
181
185
  //
182
- // ... then use the type both as JSON schema and as a TypeScript type.
186
+ // ... then use the type both as Json Schema and as a TypeScript type.
183
187
  //
184
188
  //--------------------------------------------------------------------------------------------
185
189
 
186
190
  import { Value } from '@sinclair/typebox/value'
187
191
 
188
- function receive(value: T) { // ... as a Static Type
192
+ function receive(value: T) { // ... as a Static Type
189
193
 
190
- if(Value.Check(T, value)) { // ... as a JSON Schema
194
+ if(Value.Check(T, value)) { // ... as a Json Schema
191
195
 
192
196
  // ok...
193
197
  }
@@ -198,17 +202,17 @@ function receive(value: T) { // ... as a Static Type
198
202
 
199
203
  ## Types
200
204
 
201
- TypeBox types are JSON schema fragments that compose into complex types. Each fragment is structured such that a JSON schema compliant validator can runtime assert a value the same way TypeScript will statically assert a type. TypeBox provides a set of Standard types which are used create JSON schema compliant schematics as well as an Extended type set used to create schematics for constructs native to JavaScript.
205
+ 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 create Json Schema compliant schematics as well as a JavaScript type set used to create schematics for constructs native to JavaScript.
202
206
 
203
- <a name='types-standard'></a>
207
+ <a name='types-json'></a>
204
208
 
205
- ### Standard Types
209
+ ### Json Types
206
210
 
207
- The following table lists the Standard TypeBox types. These types are fully compatible with the JSON Schema Draft 7 specification.
211
+ The following table lists the supported Json types. These types are fully compatible with the Json Schema Draft 7 specification.
208
212
 
209
213
  ```typescript
210
214
  ┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
211
- │ TypeBox │ TypeScript │ JSON Schema │
215
+ │ TypeBox │ TypeScript │ Json Schema │
212
216
  │ │ │ │
213
217
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
214
218
  │ const T = Type.Any() │ type T = any │ const T = { } │
@@ -387,12 +391,6 @@ The following table lists the Standard TypeBox types. These types are fully comp
387
391
  │ ) │ │ │
388
392
  │ │ │ │
389
393
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
390
- │ const T = Type.Pattern('^xy$') │ type T = string │ const T = { │
391
- │ │ │ type: 'string', │
392
- │ │ │ pattern: '^xy$' │
393
- │ │ │ } │
394
- │ │ │ │
395
- ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
396
394
  │ const U = Type.Union([ │ type U = 'open' | 'close' │ const T = { │
397
395
  │ Type.Literal('open'), │ │ type: 'string', │
398
396
  │ Type.Literal('close') │ type T = `on${U}` │ pattern: '^on(open|close)$' │
@@ -523,11 +521,11 @@ The following table lists the Standard TypeBox types. These types are fully comp
523
521
  └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
524
522
  ```
525
523
 
526
- <a name='types-extended'></a>
524
+ <a name='types-javascript'></a>
527
525
 
528
- ### Extended Types
526
+ ### JavaScript Types
529
527
 
530
- TypeBox provides several extended types that can be used to produce schematics for common JavaScript constructs. These types can not be used with standard JSON schema validators; but are useful to help frame schematics for RPC interfaces that may receive JSON validated data. Extended types are prefixed with the `[Extended]` doc comment for convenience. The following table lists the supported types.
528
+ 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.
531
529
 
532
530
  ```typescript
533
531
  ┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
@@ -584,6 +582,12 @@ TypeBox provides several extended types that can be used to produce schematics f
584
582
  │ │ │ } │
585
583
  │ │ │ │
586
584
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
585
+ │ const T = Type.RegExp(/abc/) │ type T = string │ const T = { │
586
+ │ │ │ type: 'string' │
587
+ │ │ │ pattern: 'abc' │
588
+ │ │ │ } │
589
+ │ │ │ │
590
+ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
587
591
  │ const T = Type.Uint8Array() │ type T = Uint8Array │ const T = { │
588
592
  │ │ │ type: 'Uint8Array' │
589
593
  │ │ │ } │
@@ -620,40 +624,40 @@ TypeBox provides several extended types that can be used to produce schematics f
620
624
 
621
625
  ### Options
622
626
 
623
- You can pass JSON Schema options on the last argument of any type. Option hints specific to each type are provided for convenience.
627
+ You can pass Json Schema options on the last argument of any type. Option hints specific to each type are provided for convenience.
624
628
 
625
629
  ```typescript
626
630
  // String must be an email
627
- const T = Type.String({ // const T = {
628
- format: 'email' // type: 'string',
629
- }) // format: 'email'
630
- // }
631
+ const T = Type.String({ // const T = {
632
+ format: 'email' // type: 'string',
633
+ }) // format: 'email'
634
+ // }
631
635
 
632
636
  // Number must be a multiple of 2
633
- const T = Type.Number({ // const T = {
634
- multipleOf: 2 // type: 'number',
635
- }) // multipleOf: 2
636
- // }
637
+ const T = Type.Number({ // const T = {
638
+ multipleOf: 2 // type: 'number',
639
+ }) // multipleOf: 2
640
+ // }
637
641
 
638
642
  // Array must have at least 5 integer values
639
- const T = Type.Array(Type.Integer(), { // const T = {
640
- minItems: 5 // type: 'array',
641
- }) // minItems: 5,
642
- // items: {
643
- // type: 'integer'
644
- // }
645
- // }
643
+ const T = Type.Array(Type.Integer(), { // const T = {
644
+ minItems: 5 // type: 'array',
645
+ }) // minItems: 5,
646
+ // items: {
647
+ // type: 'integer'
648
+ // }
649
+ // }
646
650
  ```
647
651
 
648
652
  <a name='types-properties'></a>
649
653
 
650
654
  ### Properties
651
655
 
652
- Object properties can be modified with `readonly` or `optional`. The following table shows how these modifiers map between TypeScript and JSON Schema.
656
+ Object properties can be modified with Readonly and Optional. The following table shows how these modifiers map between TypeScript and Json Schema.
653
657
 
654
658
  ```typescript
655
659
  ┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
656
- │ TypeBox │ TypeScript │ JSON Schema │
660
+ │ TypeBox │ TypeScript │ Json Schema │
657
661
  │ │ │ │
658
662
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
659
663
  │ const T = Type.Object({ │ type T = { │ const T = { │
@@ -692,31 +696,31 @@ Object properties can be modified with `readonly` or `optional`. The following t
692
696
 
693
697
  ### Generic Types
694
698
 
695
- Generic types are created with generic functions. All TypeBox types extend the sub type `TSchema` so it is common to constrain function arguments to this type. The following creates a generic `Vector<T>` type.
699
+ Generic types can be created with generic functions. All TypeBox types extend the base type TSchema; it is best practice to constrain generic arguments to this type. The following creates a generic Vector type.
696
700
 
697
701
  ```typescript
698
702
  import { Type, Static, TSchema } from '@sinclair/typebox'
699
703
 
700
704
  const Vector = <T extends TSchema>(t: T) => Type.Object({ x: t, y: t, z: t })
701
705
 
702
- const NumberVector = Vector(Type.Number()) // const NumberVector = {
703
- // type: 'object',
704
- // required: ['x', 'y', 'z'],
705
- // properties: {
706
- // x: { type: 'number' },
707
- // y: { type: 'number' },
708
- // z: { type: 'number' }
709
- // }
710
- // }
711
-
712
- type NumberVector = Static<typeof NumberVector> // type NumberVector = {
713
- // x: number,
714
- // y: number,
715
- // z: number
716
- // }
706
+ const NumberVector = Vector(Type.Number()) // const NumberVector = {
707
+ // type: 'object',
708
+ // required: ['x', 'y', 'z'],
709
+ // properties: {
710
+ // x: { type: 'number' },
711
+ // y: { type: 'number' },
712
+ // z: { type: 'number' }
713
+ // }
714
+ // }
715
+
716
+ type NumberVector = Static<typeof NumberVector> // type NumberVector = {
717
+ // x: number,
718
+ // y: number,
719
+ // z: number
720
+ // }
717
721
  ```
718
722
 
719
- Generic types can be used to create aliases for more complex types. The following creates a `Nullable<T>` type.
723
+ Generic types can be used to create aliases for more complex types. The following creates a Nullable generic type.
720
724
 
721
725
  ```typescript
722
726
  const Nullable = <T extends TSchema>(schema: T) => Type.Union([schema, Type.Null()])
@@ -735,55 +739,55 @@ type T = Static<typeof T> // type T = string | null
735
739
 
736
740
  ### Reference Types
737
741
 
738
- Reference types are supported with `Ref`.
742
+ Reference types are supported with Ref.
739
743
 
740
744
  ```typescript
741
- const T = Type.String({ $id: 'T' }) // const T = {
742
- // $id: 'T',
743
- // type: 'string'
744
- // }
745
+ const T = Type.String({ $id: 'T' }) // const T = {
746
+ // $id: 'T',
747
+ // type: 'string'
748
+ // }
745
749
 
746
- const R = Type.Ref<typeof T>('T') // const R = {
747
- // $ref: 'T'
748
- // }
750
+ const R = Type.Ref<typeof T>('T') // const R = {
751
+ // $ref: 'T'
752
+ // }
749
753
 
750
- type R = Static<typeof R> // type R = string
754
+ type R = Static<typeof R> // type R = string
751
755
  ```
752
756
 
753
757
  <a name='types-recursive'></a>
754
758
 
755
759
  ### Recursive Types
756
760
 
757
- Recursive types are supported with `Recursive`. Recursive type inference is also supported.
761
+ TypeBox supports singular recursive data structures. Recursive type inference is also supported. The following creates a recursive Node structure.
758
762
 
759
763
  ```typescript
760
- const Node = Type.Recursive(This => Type.Object({ // const Node = {
761
- id: Type.String(), // $id: 'Node',
762
- nodes: Type.Array(This) // type: 'object',
763
- }), { $id: 'Node' }) // properties: {
764
- // id: {
765
- // type: 'string'
766
- // },
767
- // nodes: {
768
- // type: 'array',
769
- // items: {
770
- // $ref: 'Node'
771
- // }
772
- // }
773
- // },
774
- // required: [
775
- // 'id',
776
- // 'nodes'
777
- // ]
778
- // }
779
-
780
- type Node = Static<typeof Node> // type Node = {
781
- // id: string
782
- // nodes: Node[]
783
- // }
764
+ const Node = Type.Recursive(This => Type.Object({ // const Node = {
765
+ id: Type.String(), // $id: 'Node',
766
+ nodes: Type.Array(This) // type: 'object',
767
+ }), { $id: 'Node' }) // properties: {
768
+ // id: {
769
+ // type: 'string'
770
+ // },
771
+ // nodes: {
772
+ // type: 'array',
773
+ // items: {
774
+ // $ref: 'Node'
775
+ // }
776
+ // }
777
+ // },
778
+ // required: [
779
+ // 'id',
780
+ // 'nodes'
781
+ // ]
782
+ // }
783
+
784
+ type Node = Static<typeof Node> // type Node = {
785
+ // id: string
786
+ // nodes: Node[]
787
+ // }
784
788
 
785
789
  function test(node: Node) {
786
- const id = node.nodes[0].nodes[0].id // id is string
790
+ const id = node.nodes[0].nodes[0].id // id is string
787
791
  }
788
792
  ```
789
793
 
@@ -791,7 +795,7 @@ function test(node: Node) {
791
795
 
792
796
  ### Conditional Types
793
797
 
794
- TypeBox supports conditional types with `Extends`. This type performs a structural assignment check against the first two parameters and returns either the `true` or `false` type as given from the second two parameters. The conditional types `Exclude` and `Extract` are also supported.
798
+ TypeBox supports conditional types with Extends. This type performs a structural assignability check for the first two arguments and returns either of the second two arguments based on the result. This type is modelled after TypeScript conditional types. The Exclude and Extract conditional types are also supported.
795
799
 
796
800
  ```typescript
797
801
  // TypeScript
@@ -834,143 +838,153 @@ const T2 = Type.Exclude( // const T2: TUnion<[
834
838
  // }
835
839
  ```
836
840
 
837
- <a name='types-template-literal'></a>
841
+ <a name='types-templateliteral'></a>
838
842
 
839
843
  ### Template Literal Types
840
844
 
841
- TypeBox supports template literal types with `TemplateLiteral`. This type provides an embedded DSL syntax that is similar to the TypeScript template literal syntax. These type can also be composed by passing a tuple of exterior union and literal types. The following example shows the DSL syntax.
845
+ TypeBox supports template literal types with TemplateLiteral. This type can be created using a string syntax that is partially modelled on the TypeScript template literal syntax. This type can also be constructed by passing an array of Union and Literal types in sequence. The following example shows the string syntax.
842
846
 
843
847
  ```typescript
844
848
  // TypeScript
845
849
 
846
- type T = `option${'A'|'B'|'C'}` // type T = 'optionA' | 'optionB' | 'optionC'
850
+ type T = `option${'A'|'B'|'C'}` // type T = 'optionA' | 'optionB' | 'optionC'
847
851
 
848
- type R = Record<T, string> // type R = {
849
- // optionA: string
850
- // optionB: string
851
- // optionC: string
852
- // }
852
+ type R = Record<T, string> // type R = {
853
+ // optionA: string
854
+ // optionB: string
855
+ // optionC: string
856
+ // }
853
857
 
854
858
  // TypeBox
855
859
 
856
- const T = Type.TemplateLiteral('option${A|B|C}') // const T = {
857
- // pattern: '^option(A|B|C)$',
858
- // type: 'string'
859
- // }
860
-
861
- const R = Type.Record(T, Type.String()) // const R = {
862
- // type: 'object',
863
- // required: ['optionA', 'optionB'],
864
- // properties: {
865
- // optionA: {
866
- // type: 'string'
867
- // },
868
- // optionB: {
869
- // type: 'string'
870
- // }
871
- // optionC: {
872
- // type: 'string'
873
- // }
874
- // }
875
- // }
860
+ const T = Type.TemplateLiteral('option${A|B|C}') // const T = {
861
+ // pattern: '^option(A|B|C)$',
862
+ // type: 'string'
863
+ // }
864
+
865
+ const R = Type.Record(T, Type.String()) // const R = {
866
+ // type: 'object',
867
+ // required: ['optionA', 'optionB'],
868
+ // properties: {
869
+ // optionA: {
870
+ // type: 'string'
871
+ // },
872
+ // optionB: {
873
+ // type: 'string'
874
+ // }
875
+ // optionC: {
876
+ // type: 'string'
877
+ // }
878
+ // }
879
+ // }
876
880
  ```
877
881
 
878
882
  <a name='types-indexed'></a>
879
883
 
880
884
  ### Indexed Access Types
881
885
 
882
- TypeBox supports indexed access types using `Index`. This type provides a consistent way of accessing interior property and array element types without having to extract them from the underlying schema representation. Indexed access types are supported for object, array, tuple, union and intersect types.
886
+ TypeBox supports Indexed Access Types with the Index type. This type offers a uniform way to access interior property and array element types without having to extract them from the underlying schema representation. This type is supported for Object, Array, Tuple, Union and Intersect types.
883
887
 
884
888
  ```typescript
885
- const T = Type.Object({ // const T = {
886
- x: Type.Number(), // type: 'object',
887
- y: Type.String(), // required: ['x', 'y', 'z'],
888
- z: Type.Boolean() // properties: {
889
- }) // x: { type: 'number' },
890
- // y: { type: 'string' },
891
- // z: { type: 'string' }
892
- // }
893
- // }
894
-
895
- const A = Type.Index(T, ['x']) // const A = { type: 'number' }
896
-
897
- const B = Type.Index(T, ['x', 'y']) // const B = {
898
- // anyOf: [
899
- // { type: 'number' },
900
- // { type: 'string' }
901
- // ]
902
- // }
903
-
904
- const C = Type.Index(T, Type.KeyOf(T)) // const C = {
905
- // anyOf: [
906
- // { type: 'number' },
907
- // { type: 'string' },
908
- // { type: 'boolean' }
909
- // ]
910
- // }
889
+ const T = Type.Object({ // const T = {
890
+ x: Type.Number(), // type: 'object',
891
+ y: Type.String(), // required: ['x', 'y', 'z'],
892
+ z: Type.Boolean() // properties: {
893
+ }) // x: { type: 'number' },
894
+ // y: { type: 'string' },
895
+ // z: { type: 'string' }
896
+ // }
897
+ // }
898
+
899
+ const A = Type.Index(T, ['x']) // const A = { type: 'number' }
900
+
901
+ const B = Type.Index(T, ['x', 'y']) // const B = {
902
+ // anyOf: [
903
+ // { type: 'number' },
904
+ // { type: 'string' }
905
+ // ]
906
+ // }
907
+
908
+ const C = Type.Index(T, Type.KeyOf(T)) // const C = {
909
+ // anyOf: [
910
+ // { type: 'number' },
911
+ // { type: 'string' },
912
+ // { type: 'boolean' }
913
+ // ]
914
+ // }
911
915
  ```
912
916
 
913
- <a name='types-negated'></a>
917
+ <a name='types-rest'></a>
914
918
 
915
- ### Negated Types
919
+ ### Rest Types
916
920
 
917
- TypeBox has support for type negation with `Not`. This type will always infer as `unknown`.
921
+ TypeBox provides the Rest type to uniformly extract the variadic tuple passed to Intersect, Union and Tuple types. This type can be useful to remap variadic types into different forms. The following uses the Rest type to remap a Tuple into a Union.
918
922
 
919
923
  ```typescript
920
- const T = Type.Not(Type.String()) // const T = {
921
- // not: { type: 'string' }
924
+ const T = Type.Tuple([ // const T = {
925
+ Type.String(), // type: 'array',
926
+ Type.Number() // items: [
927
+ ]) // { type: 'string' },
928
+ // { type: 'number' }
929
+ // ],
930
+ // additionalItems: false,
931
+ // minItems: 2,
932
+ // maxItems: 2,
922
933
  // }
923
934
 
924
- type T = Static<typeof T> // type T = unknown
925
- //
926
- // where T could be any type other than string
935
+ const R = Type.Rest(T) // const R = [
936
+ // { type: 'string' },
937
+ // { type: 'number' }
938
+ // ]
939
+
940
+ const U = Type.Union(R) // const U = {
941
+ // anyOf: [
942
+ // { type: 'string' },
943
+ // { type: 'number' }
944
+ // ]
945
+ // }
927
946
  ```
928
- Type negation can be useful for certain forms of type narrowing. For example, consider a type that represents a `number` but not the numbers `1, 2, 3`. The example below shows an imaginary TypeScript syntax to express such a type followed by the TypeBox representation.
929
947
 
930
- ```typescript
931
- // TypeScript
948
+ <a name='types-transform'></a>
932
949
 
933
- type T = number & not (1 | 2 | 3) // not actual syntax
950
+ ### Transform Types
934
951
 
935
- // TypeBox
952
+ TypeBox supports bi-directional value encoding and decoding with Transform types. These types are designed to operate specifically with the Value and TypeCompiler Encode and Decode functions. Transform types can be used to convert Json encoded values into constructs more natural to JavaScript. The following creates a Transform type to convert between Date and number using the Value module.
953
+
954
+ ```typescript
955
+ import { Value } from '@sinclair/typebox/value'
956
+
957
+ const T = Type.Transform(Type.Number())
958
+ .Decode(value => new Date(value)) // required: number to Date
959
+ .Encode(value => value.getTime()) // required: Date to number
936
960
 
937
- const T = Type.Intersect([ // const T = {
938
- Type.Number(), // allOf: [
939
- Type.Not(Type.Union([ // { type: "number" },
940
- Type.Literal(1), // {
941
- Type.Literal(2), // not: {
942
- Type.Literal(3) // anyOf: [
943
- ])) // { const: 1, type: "number" },
944
- ]) // { const: 2, type: "number" },
945
- // { const: 3, type: "number" }
946
- // ]
947
- // }
948
- // }
949
- // ]
950
- // }
951
-
952
- type T = Static<typeof T> // type T = number
961
+ const decoded = Value.Decode(T, 0) // const decoded = Date(1970-01-01T00:00:00.000Z)
962
+ const encoded = Value.Encode(T, decoded) // const encoded = 0
953
963
  ```
954
- This type can be used with constraints to create schematics that would otherwise be difficult to express.
964
+ Use the StaticEncode or StaticDecode types to infer a Transform type.
955
965
  ```typescript
956
- const Even = Type.Number({ multipleOf: 2 })
966
+ import { Static, StaticDecode, StaticEncode } from '@sinclair/typebox'
957
967
 
958
- const Odd = Type.Intersect([Type.Number(), Type.Not(Even)])
968
+ const T = Type.Transform(Type.Array(Type.Number(), { uniqueItems: true }))
969
+ .Decode(value => new Set(value))
970
+ .Encode(value => [...value])
971
+
972
+ type D = StaticDecode<typeof T> // type D = Set<number>
973
+ type E = StaticEncode<typeof T> // type E = Array<number>
974
+ type T = Static<typeof T> // type T = Array<number>
959
975
  ```
960
976
 
961
977
  <a name='types-intrinsic'></a>
962
978
 
963
- ### Intrinsic String Types
979
+ ### Intrinsic Types
964
980
 
965
- TypeBox supports TypeScript intrinsic string manipulation types `Uppercase`, `Lowercase`, `Capitalize` and `Uncapitalize`. These can be applied to string literals, template literals and unions. The following shows general usage.
981
+ TypeBox supports the TypeScript Intrinsic String Manipulation types Uppercase, Lowercase, Capitalize and Uncapitalize. These types can be used to remap String Literal, TemplateLiteral and Union types. The following shows general usage.
966
982
 
967
983
  ```typescript
968
984
  // TypeScript
969
985
 
970
986
  type A = Capitalize<'hello'> // type A = 'Hello'
971
-
972
987
  type B = Capitalize<'hello' | 'world'> // type C = 'Hello' | 'World'
973
-
974
988
  type C = Capitalize<`hello${1|2|3}`> // type B = 'Hello1' | 'Hello2' | 'Hello3'
975
989
 
976
990
  // TypeBox
@@ -992,94 +1006,47 @@ const C = Type.Capitalize( // const C: TTemplateLiteral
992
1006
  // ]>
993
1007
  ```
994
1008
 
995
- <a name='types-rest'></a>
996
-
997
- ### Rest Types
998
-
999
- Rest parameters are supported with `Rest`. This function is used to extract interior type elements from tuples which enables them to compose with the JavaScript spread operator `...`. This type can be used for tuple concatenation as well function parameter assignment.
1000
-
1001
- ```typescript
1002
- // TypeScript
1003
-
1004
- type T = [number, number] // type T = [number, number]
1005
-
1006
- type C = [...T, number] // type C = [number, number, number]
1007
-
1008
- type F = (...param: C) => void // type F = (
1009
- // param0: number,
1010
- // param1: number,
1011
- // param2: number
1012
- // ) => void
1013
-
1014
- // TypeBox
1015
-
1016
- const T = Type.Tuple([ // const T: TTuple<[
1017
- Type.Number(), // TNumber,
1018
- Type.Number() // TNumber
1019
- ]) // ]>
1020
-
1021
- const C = Type.Tuple([ // const C: TTuple<[
1022
- ...Type.Rest(T), // TNumber,
1023
- Type.Number() // TNumber,
1024
- ]) // TNumber
1025
- // ]>
1026
-
1027
- const F = Type.Function(Type.Rest(C), Type.Void()) // const F: TFunction<[
1028
- // TNumber,
1029
- // TNumber,
1030
- // TNumber
1031
- // ], TVoid>
1032
- ```
1033
1009
  <a name='types-unsafe'></a>
1034
1010
 
1035
1011
  ### Unsafe Types
1036
1012
 
1037
- TypeBox supports the creation of user defined schematics with user defined inference rules using the Unsafe type.
1013
+ TypeBox supports user defined types with Unsafe. This type allows you to specify both schema representation and inference type. The following creates an Unsafe type with a number schema that infers as string.
1038
1014
 
1039
1015
  ```typescript
1040
- const T = Type.Unsafe<string>({ type: 'number' }) // const T = {
1041
- // type: 'number'
1042
- // }
1016
+ const T = Type.Unsafe<string>({ type: 'number' }) // const T = {
1017
+ // type: 'number'
1018
+ // }
1043
1019
 
1044
- type T = Static<typeof T> // type T = string
1020
+ type T = Static<typeof T> // type T = string ?
1045
1021
  ```
1046
-
1047
- This type can be useful to create various extended schematics, such as those used by OpenAPI.
1048
-
1022
+ The Unsafe type are often used to create schematics for specifications like OpenAPI
1049
1023
  ```typescript
1050
- import { Type, Static, TSchema } from '@sinclair/typebox'
1051
-
1052
- // Nullable<T>
1053
1024
 
1054
- function Nullable<T extends TSchema>(schema: T) {
1055
- return Type.Unsafe<Static<T> | null>({ ...schema, nullable: true })
1056
- }
1057
-
1058
- const T = Nullable(Type.String()) // const T = {
1059
- // type: 'string',
1060
- // nullable: true
1061
- // }
1062
-
1063
- type T = Static<typeof T> // type T = string | null
1025
+ const Nullable = <T extends TSchema>(schema: T) => Type.Unsafe<Static<T> | null>({
1026
+ ...schema, nullable: true
1027
+ })
1064
1028
 
1065
- // StringEnum<string[]>
1029
+ const T = Nullable(Type.String()) // const T = {
1030
+ // type: 'string',
1031
+ // nullable: true
1032
+ // }
1066
1033
 
1067
- function StringEnum<T extends string[]>(values: [...T]) {
1068
- return Type.Unsafe<T[number]>({ type: 'string', enum: values })
1069
- }
1034
+ type T = Static<typeof T> // type T = string | null
1070
1035
 
1071
- const T = StringEnum(['A', 'B', 'C']) // const T = {
1072
- // enum: ['A', 'B', 'C']
1073
- // }
1036
+ const StringEnum = <T extends string[]>(values: [...T]) => Type.Unsafe<T[number]>({
1037
+ type: 'string', enum: values
1038
+ })
1039
+ const S = StringEnum(['A', 'B', 'C']) // const S = {
1040
+ // enum: ['A', 'B', 'C']
1041
+ // }
1074
1042
 
1075
- type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
1043
+ type S = Static<typeof T> // type S = 'A' | 'B' | 'C'
1076
1044
  ```
1077
-
1078
1045
  <a name='types-guards'></a>
1079
1046
 
1080
1047
  ### Type Guards
1081
1048
 
1082
- TypeBox provides a TypeGuard module to assert JavaScript values are valid TypeBox types.
1049
+ TypeBox provides a TypeGuard module to check JavaScript values are valid TypeBox types. The following checks the value T is TString.
1083
1050
 
1084
1051
  ```typescript
1085
1052
  import { Type, Kind, TypeGuard } from '@sinclair/typebox'
@@ -1096,36 +1063,36 @@ if(TypeGuard.TString(T)) {
1096
1063
 
1097
1064
  ### Strict
1098
1065
 
1099
- TypeBox types contain various symbol properties that are used for reflection, composition and compilation. These properties are not strictly valid JSON schema; so in some cases it may be desirable to omit them. TypeBox provides a `Strict` function that will omit these properties if necessary.
1066
+ TypeBox types contain various symbol properties that are used for reflection, composition and compilation. These properties are not strictly valid Json Schema; so in some cases it may be desirable to omit them. TypeBox provides a `Strict` function that will omit these properties if necessary.
1100
1067
 
1101
1068
  ```typescript
1102
- const T = Type.Object({ // const T = {
1103
- name: Type.Optional(Type.String()) // [Kind]: 'Object',
1104
- }) // type: 'object',
1105
- // properties: {
1106
- // name: {
1107
- // type: 'string',
1108
- // [Kind]: 'String',
1109
- // [Optional]: 'Optional'
1110
- // }
1111
- // }
1112
- // }
1113
-
1114
- const U = Type.Strict(T) // const U = {
1115
- // type: 'object',
1116
- // properties: {
1117
- // name: {
1118
- // type: 'string'
1119
- // }
1120
- // }
1121
- // }
1069
+ const T = Type.Object({ // const T = {
1070
+ name: Type.Optional(Type.String()) // [Kind]: 'Object',
1071
+ }) // type: 'object',
1072
+ // properties: {
1073
+ // name: {
1074
+ // type: 'string',
1075
+ // [Kind]: 'String',
1076
+ // [Optional]: 'Optional'
1077
+ // }
1078
+ // }
1079
+ // }
1080
+
1081
+ const U = Type.Strict(T) // const U = {
1082
+ // type: 'object',
1083
+ // properties: {
1084
+ // name: {
1085
+ // type: 'string'
1086
+ // }
1087
+ // }
1088
+ // }
1122
1089
  ```
1123
1090
 
1124
1091
  <a name='values'></a>
1125
1092
 
1126
1093
  ## Values
1127
1094
 
1128
- TypeBox provides an optional utility module that can be used to perform common operations on JavaScript values. This module includes functionality to create, check and cast values from types as well as check equality, clone, diff and patch JavaScript values. This module is provided via optional import.
1095
+ TypeBox provides an optional utility module that can be used to perform structural operations on JavaScript values. This module includes functionality to create, check and cast values from types as well as check equality, clone, diff and patch JavaScript values. This module is provided via optional import.
1129
1096
 
1130
1097
  ```typescript
1131
1098
  import { Value } from '@sinclair/typebox/value'
@@ -1140,7 +1107,7 @@ Use the Create function to create a value from a type. TypeBox will use default
1140
1107
  ```typescript
1141
1108
  const T = Type.Object({ x: Type.Number(), y: Type.Number({ default: 42 }) })
1142
1109
 
1143
- const A = Value.Create(T) // const A = { x: 0, y: 42 }
1110
+ const A = Value.Create(T) // const A = { x: 0, y: 42 }
1144
1111
  ```
1145
1112
 
1146
1113
  <a name='values-clone'></a>
@@ -1150,7 +1117,7 @@ const A = Value.Create(T) // const A = { x: 0, y: 42
1150
1117
  Use the Clone function to deeply clone a value
1151
1118
 
1152
1119
  ```typescript
1153
- const A = Value.Clone({ x: 1, y: 2, z: 3 }) // const A = { x: 1, y: 2, z: 3 }
1120
+ const A = Value.Clone({ x: 1, y: 2, z: 3 }) // const A = { x: 1, y: 2, z: 3 }
1154
1121
  ```
1155
1122
 
1156
1123
  <a name='values-check'></a>
@@ -1162,14 +1129,14 @@ Use the Check function to type check a value
1162
1129
  ```typescript
1163
1130
  const T = Type.Object({ x: Type.Number() })
1164
1131
 
1165
- const R = Value.Check(T, { x: 1 }) // const R = true
1132
+ const R = Value.Check(T, { x: 1 }) // const R = true
1166
1133
  ```
1167
1134
 
1168
1135
  <a name='values-convert'></a>
1169
1136
 
1170
1137
  ### Convert
1171
1138
 
1172
- Use the Convert function to convert a value into its target type if a reasonable conversion is possible. This function may return an invalid value and should be checked before use. It's return type is `unknown`.
1139
+ Use the Convert function to convert a value into its target type if a reasonable conversion is possible. This function may return an invalid value and should be checked before use. Its return type is `unknown`.
1173
1140
 
1174
1141
  ```typescript
1175
1142
  const T = Type.Object({ x: Type.Number() })
@@ -1188,11 +1155,33 @@ Use the Cast function to cast a value into a type. The cast function will retain
1188
1155
  ```typescript
1189
1156
  const T = Type.Object({ x: Type.Number(), y: Type.Number() }, { additionalProperties: false })
1190
1157
 
1191
- const X = Value.Cast(T, null) // const X = { x: 0, y: 0 }
1158
+ const X = Value.Cast(T, null) // const X = { x: 0, y: 0 }
1159
+
1160
+ const Y = Value.Cast(T, { x: 1 }) // const Y = { x: 1, y: 0 }
1161
+
1162
+ const Z = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const Z = { x: 1, y: 2 }
1163
+ ```
1164
+
1165
+ <a name='values-decode'></a>
1166
+
1167
+ ### Decode
1168
+
1169
+ Use the Decode function to decode a value from a type or throw if the value is invalid. The return value will infer as the given type. This function will run Transform decode functions if available.
1170
+
1171
+ ```typescript
1172
+ const A = Type.Decode(Type.String(), 'hello') // const A = 'hello'
1173
+
1174
+ const B = Type.Decode(Type.String(), 42) // throw
1175
+ ```
1176
+ <a name='values-decode'></a>
1192
1177
 
1193
- const Y = Value.Cast(T, { x: 1 }) // const Y = { x: 1, y: 0 }
1178
+ ### Encode
1194
1179
 
1195
- const Z = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const Z = { x: 1, y: 2 }
1180
+ Use the Encode function to encode a value from a type or throw if the value is invalid. The return value will infer as the given type. This function will run Transform encode functions if available. When encoding with types without Transforms, this function is equivalent to Decode.
1181
+ ```typescript
1182
+ const A = Type.Encode(Type.String(), 'hello') // const A = 'hello'
1183
+
1184
+ const B = Type.Encode(Type.String(), 42) // throw
1196
1185
  ```
1197
1186
 
1198
1187
  <a name='values-equal'></a>
@@ -1202,7 +1191,7 @@ const Z = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const Z = { x: 1, y: 2 }
1202
1191
  Use the Equal function to deeply check for value equality.
1203
1192
 
1204
1193
  ```typescript
1205
- const R = Value.Equal( // const R = true
1194
+ const R = Value.Equal( // const R = true
1206
1195
  { x: 1, y: 2, z: 3 },
1207
1196
  { x: 1, y: 2, z: 3 }
1208
1197
  )
@@ -1239,19 +1228,19 @@ const E = Value.Diff( // const E = [
1239
1228
 
1240
1229
  ### Patch
1241
1230
 
1242
- Use the Patch function to apply edits
1231
+ Use the Patch function to apply Diff edits
1243
1232
 
1244
1233
  ```typescript
1245
1234
  const A = { x: 1, y: 2 }
1246
1235
 
1247
1236
  const B = { x: 3 }
1248
1237
 
1249
- const E = Value.Diff(A, B) // const E = [
1250
- // { type: 'update', path: '/x', value: 3 },
1251
- // { type: 'delete', path: '/y' }
1252
- // ]
1238
+ const E = Value.Diff(A, B) // const E = [
1239
+ // { type: 'update', path: '/x', value: 3 },
1240
+ // { type: 'delete', path: '/y' }
1241
+ // ]
1253
1242
 
1254
- const C = Value.Patch<typeof B>(A, E) // const C = { x: 3 }
1243
+ const C = Value.Patch<typeof B>(A, E) // const C = { x: 3 }
1255
1244
  ```
1256
1245
 
1257
1246
  <a name='values-errors'></a>
@@ -1263,17 +1252,17 @@ Use the Errors function enumerate validation errors.
1263
1252
  ```typescript
1264
1253
  const T = Type.Object({ x: Type.Number(), y: Type.Number() })
1265
1254
 
1266
- const R = [...Value.Errors(T, { x: '42' })] // const R = [{
1267
- // schema: { type: 'number' },
1268
- // path: '/x',
1269
- // value: '42',
1270
- // message: 'Expected number'
1271
- // }, {
1272
- // schema: { type: 'number' },
1273
- // path: '/y',
1274
- // value: undefined,
1275
- // message: 'Expected number'
1276
- // }]
1255
+ const R = [...Value.Errors(T, { x: '42' })] // const R = [{
1256
+ // schema: { type: 'number' },
1257
+ // path: '/x',
1258
+ // value: '42',
1259
+ // message: 'Expected number'
1260
+ // }, {
1261
+ // schema: { type: 'number' },
1262
+ // path: '/y',
1263
+ // value: undefined,
1264
+ // message: 'Expected number'
1265
+ // }]
1277
1266
  ```
1278
1267
 
1279
1268
  <a name='values-mutate'></a>
@@ -1283,47 +1272,87 @@ const R = [...Value.Errors(T, { x: '42' })] // const R = [{
1283
1272
  Use the Mutate function to perform a deep mutable value assignment while retaining internal references.
1284
1273
 
1285
1274
  ```typescript
1286
- const Y = { z: 1 } // const Y = { z: 1 }
1275
+ const Y = { z: 1 } // const Y = { z: 1 }
1287
1276
 
1288
- const X = { y: Y } // const X = { y: { z: 1 } }
1277
+ const X = { y: Y } // const X = { y: { z: 1 } }
1289
1278
 
1290
- const A = { x: X } // const A = { x: { y: { z: 1 } } }
1279
+ const A = { x: X } // const A = { x: { y: { z: 1 } } }
1291
1280
 
1292
1281
 
1293
- Value.Mutate(A, { x: { y: { z: 2 } } }) // const A' = { x: { y: { z: 2 } } }
1282
+ Value.Mutate(A, { x: { y: { z: 2 } } }) // const A' = { x: { y: { z: 2 } } }
1294
1283
 
1295
- const R0 = A.x.y.z === 2 // const R0 = true
1284
+ const R0 = A.x.y.z === 2 // const R0 = true
1296
1285
 
1297
- const R1 = A.x.y === Y // const R1 = true
1286
+ const R1 = A.x.y === Y // const R1 = true
1298
1287
 
1299
- const R2 = A.x === X // const R2 = true
1288
+ const R2 = A.x === X // const R2 = true
1300
1289
  ```
1301
1290
 
1302
1291
  <a name='values-pointer'></a>
1303
1292
 
1304
1293
  ### Pointer
1305
1294
 
1306
- Use ValuePointer to perform mutable updates on existing values using [RFC6901](https://www.rfc-editor.org/rfc/rfc6901) JSON Pointers.
1295
+ Use ValuePointer to perform mutable updates on existing values using [RFC6901](https://www.rfc-editor.org/rfc/rfc6901) Json Pointers.
1307
1296
 
1308
1297
  ```typescript
1309
1298
  import { ValuePointer } from '@sinclair/typebox/value'
1310
1299
 
1311
1300
  const A = { x: 0, y: 0, z: 0 }
1312
1301
 
1313
- ValuePointer.Set(A, '/x', 1) // const A' = { x: 1, y: 0, z: 0 }
1302
+ ValuePointer.Set(A, '/x', 1) // const A' = { x: 1, y: 0, z: 0 }
1314
1303
 
1315
- ValuePointer.Set(A, '/y', 1) // const A' = { x: 1, y: 1, z: 0 }
1304
+ ValuePointer.Set(A, '/y', 1) // const A' = { x: 1, y: 1, z: 0 }
1316
1305
 
1317
- ValuePointer.Set(A, '/z', 1) // const A' = { x: 1, y: 1, z: 1 }
1306
+ ValuePointer.Set(A, '/z', 1) // const A' = { x: 1, y: 1, z: 1 }
1307
+ ```
1308
+
1309
+ <a name='typeregistry'></a>
1310
+
1311
+ ## TypeRegistry
1312
+
1313
+ The TypeBox type system can be extended with additional types and formats using the TypeRegistry and FormatRegistry modules. These modules integrate deeply with TypeBox's internal type checking infrastructure and can be used to create application specific types, or express schematics for alternative schema specifications.
1314
+
1315
+ <a name='typeregistry-type'></a>
1316
+
1317
+ ### TypeRegistry
1318
+
1319
+ Use the TypeRegistry to register a new type. The Kind must match the registered type name.
1320
+
1321
+ ```typescript
1322
+ import { TypeRegistry, Kind } from '@sinclair/typebox'
1323
+
1324
+ TypeRegistry.Set('Foo', (schema, value) => value === 'foo')
1325
+
1326
+ const A = Value.Check({ [Kind]: 'Foo' }, 'foo') // const A = true
1327
+
1328
+ const B = Value.Check({ [Kind]: 'Foo' }, 'bar') // const B = false
1329
+ ```
1330
+
1331
+ <a name='typeregistry-format'></a>
1332
+
1333
+ ### FormatRegistry
1334
+
1335
+ Use the FormatRegistry to register a string format.
1336
+
1337
+ ```typescript
1338
+ import { FormatRegistry } from '@sinclair/typebox'
1339
+
1340
+ FormatRegistry.Set('foo', (value) => value === 'foo')
1341
+
1342
+ const T = Type.String({ format: 'foo' })
1343
+
1344
+ const A = Value.Check(T, 'foo') // const A = true
1345
+
1346
+ const B = Value.Check(T, 'bar') // const B = false
1318
1347
  ```
1319
1348
 
1320
1349
  <a name='typecheck'></a>
1321
1350
 
1322
1351
  ## TypeCheck
1323
1352
 
1324
- TypeBox types target JSON Schema draft 7 so are compatible with any validator that supports this specification. TypeBox also provides a built in type checking compiler designed specifically for high performance compilation and value assertion.
1353
+ TypeBox types target Json Schema Draft 7 and are compatible with any validator that supports this specification. TypeBox also provides a built in type checking compiler designed specifically for TypeBox types that offers high performance compilation and value assertion.
1325
1354
 
1326
- The following sections detail using Ajv and TypeBox's compiler infrastructure.
1355
+ The following sections detail using Ajv and the TypeBox compiler infrastructure.
1327
1356
 
1328
1357
  <a name='typecheck-ajv'></a>
1329
1358
 
@@ -1357,20 +1386,20 @@ const ajv = addFormats(new Ajv({}), [
1357
1386
  'regex'
1358
1387
  ])
1359
1388
 
1360
- const C = ajv.compile(Type.Object({
1389
+ const validate = ajv.compile(Type.Object({
1361
1390
  x: Type.Number(),
1362
1391
  y: Type.Number(),
1363
1392
  z: Type.Number()
1364
1393
  }))
1365
1394
 
1366
- const R = C({ x: 1, y: 2, z: 3 }) // const R = true
1395
+ const R = validate({ x: 1, y: 2, z: 3 }) // const R = true
1367
1396
  ```
1368
1397
 
1369
1398
  <a name='typecheck-typecompiler'></a>
1370
1399
 
1371
1400
  ### TypeCompiler
1372
1401
 
1373
- The TypeBox TypeCompiler is a high performance JIT compiler that transforms TypeBox types into optimized JavaScript validation routines. The compiler is tuned for fast compilation as well as fast value assertion. It is designed to serve as a validation backend that can be integrated into larger applications; but can also be used as a general purpose validator.
1402
+ The TypeBox TypeCompiler is a high performance JIT compiler that transforms TypeBox types into optimized JavaScript validation routines. The compiler is tuned for fast compilation as well as fast assertion. It is built to serve as a validation backend that can be integrated into larger applications and frameworks; but can also be used as a general purpose validator.
1374
1403
 
1375
1404
  The TypeCompiler is provided as an optional import.
1376
1405
 
@@ -1378,157 +1407,209 @@ The TypeCompiler is provided as an optional import.
1378
1407
  import { TypeCompiler } from '@sinclair/typebox/compiler'
1379
1408
  ```
1380
1409
 
1381
- Use the `Compile(...)` function to compile a type. Note that compilation is an expensive operation that should typically be performed once per type during application start up. TypeBox does not cache previously compiled types, so applications are expected to hold references to each compiled type for the lifetime of the application.
1410
+ Use the Compile function to JIT compile a type. Note that compilation is generally an expensive operation and should only be performed once per type during application start up. TypeBox does not cache previously compiled types, and applications are expected to hold references to each compiled type for the lifetime of the application.
1382
1411
 
1383
1412
  ```typescript
1384
- const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObject<{
1385
- x: Type.Number(), // x: TNumber;
1386
- y: Type.Number(), // y: TNumber;
1387
- z: Type.Number() // z: TNumber;
1388
- })) // }>>
1413
+ const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObject<{
1414
+ x: Type.Number(), // x: TNumber;
1415
+ y: Type.Number(), // y: TNumber;
1416
+ z: Type.Number() // z: TNumber;
1417
+ })) // }>>
1389
1418
 
1390
- const R = C.Check({ x: 1, y: 2, z: 3 }) // const R = true
1419
+ const R = C.Check({ x: 1, y: 2, z: 3 }) // const R = true
1391
1420
  ```
1392
1421
 
1393
- Use the `Errors(...)` function to produce diagnostic errors for a value. The `Errors(...)` function will return an iterator that if enumerated; will perform an exhaustive check across the entire value and yield any error found. For performance, this function should only be called after failed `Check(...)`. Applications may also choose to yield only the first value to avoid exhaustive error generation.
1422
+ Use the Errors function to generate diagnostic errors for a value. The Errors function will return an iterator that when enumerated; will perform an exhaustive check across the entire value yielding any error found. For performance, this function should only be called after failed Check. Applications may also choose to yield only the first value to avoid exhaustive error generation.
1394
1423
 
1395
1424
  ```typescript
1396
- const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObject<{
1397
- x: Type.Number(), // x: TNumber;
1398
- y: Type.Number(), // y: TNumber;
1399
- z: Type.Number() // z: TNumber;
1400
- })) // }>>
1425
+ const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObject<{
1426
+ x: Type.Number(), // x: TNumber;
1427
+ y: Type.Number(), // y: TNumber;
1428
+ z: Type.Number() // z: TNumber;
1429
+ })) // }>>
1401
1430
 
1402
1431
  const value = { }
1403
1432
 
1404
- const errors = [...C.Errors(value)] // const errors = [{
1405
- // schema: { type: 'number' },
1406
- // path: '/x',
1407
- // value: undefined,
1408
- // message: 'Expected number'
1409
- // }, {
1410
- // schema: { type: 'number' },
1411
- // path: '/y',
1412
- // value: undefined,
1413
- // message: 'Expected number'
1414
- // }, {
1415
- // schema: { type: 'number' },
1416
- // path: '/z',
1417
- // value: undefined,
1418
- // message: 'Expected number'
1419
- // }]
1420
- ```
1421
-
1422
- Compiled routines can be inspected with the `.Code()` function.
1433
+ const first = C.Errors(value).First() // const first = {
1434
+ // schema: { type: 'number' },
1435
+ // path: '/x',
1436
+ // value: undefined,
1437
+ // message: 'Expected number'
1438
+ // }
1423
1439
 
1440
+ const all = [...C.Errors(value)] // const all = [{
1441
+ // schema: { type: 'number' },
1442
+ // path: '/x',
1443
+ // value: undefined,
1444
+ // message: 'Expected number'
1445
+ // }, {
1446
+ // schema: { type: 'number' },
1447
+ // path: '/y',
1448
+ // value: undefined,
1449
+ // message: 'Expected number'
1450
+ // }, {
1451
+ // schema: { type: 'number' },
1452
+ // path: '/z',
1453
+ // value: undefined,
1454
+ // message: 'Expected number'
1455
+ // }]
1456
+ ```
1457
+ Use the Code function to generate assertion functions as strings. This function can be used to create high performance assertions that can be written to disk as importable modules. TypeBox supports both TypeScript and JavaScript code generation. The following generates TypeScript.
1424
1458
  ```typescript
1425
- const C = TypeCompiler.Compile(Type.String()) // const C: TypeCheck<TString>
1426
-
1427
- console.log(C.Code()) // return function check(value) {
1428
- // return (
1429
- // (typeof value === 'string')
1430
- // )
1431
- // }
1459
+ const C = TypeCompiler.Code(Type.String({ // const C = `return function check(value: any): boolean {
1460
+ language: 'typescript' // return (
1461
+ }) // (typeof value === 'string')
1462
+ // )
1463
+ // }`
1432
1464
  ```
1433
1465
 
1434
1466
  <a name='typesystem'></a>
1435
1467
 
1436
1468
  ## TypeSystem
1437
1469
 
1438
- The TypeBox TypeSystem module provides functionality to define types above and beyond the Standard and Extended type sets as well as control various assertion policies. Configurations made to the TypeSystem module are observed by both `TypeCompiler` and `Value` modules.
1439
-
1440
- The TypeSystem module is provided as an optional import.
1441
-
1442
- ```typescript
1443
- import { TypeSystem } from '@sinclair/typebox/system'
1444
- ```
1470
+ The TypeBox TypeSystem modules provides additional functionality to define types above and beyond the Json and JavaScript type sets. They also manage TypeBox's localization options (i18n) for error message generation and can control various internal assertion policies used for type checking. Configurations made to the TypeSystem module are observed by TypeCompiler, Value and Error modules.
1445
1471
 
1446
1472
  <a name='typesystem-types'></a>
1447
1473
 
1448
1474
  ### Types
1449
1475
 
1450
- Use the `Type(...)` function to create custom types. This function lets you specify custom value assertion logic and will return a type factory function which is used to instance the type. This function accepts two generic arguments, the first is the inference type, the second is options used to constrain the type. The following creates a Vector type.
1476
+ Use the TypeSystem Type function to register a user defined type.
1451
1477
 
1452
1478
  ```typescript
1453
- type VectorOptions = { abs: boolean }
1454
-
1455
- type Vector = { x: number, y: number }
1479
+ import { TypeSystem } from '@sinclair/typebox/system'
1456
1480
 
1457
- const Vector = TypeSystem.Type<Vector, VectorOptions>('Vector', (options, value) => {
1458
- return (
1459
- typeof value === 'object' && value !== null &&
1460
- 'x' in value && typeof value.x === 'number' &&
1461
- 'y' in value && typeof value.y === 'number' &&
1462
- (options.abs ? (value.x === Math.abs(value.x) && value.y === Math.abs(value.y)) : true)
1463
- )
1481
+ const StringSet = TypeSystem.Type<Set<string>>('StringSet', (options, value) => {
1482
+ return value instanceof Set && [...value].every(value => typeof value === 'string')
1464
1483
  })
1465
1484
 
1466
- const T = Vector({ abs: true })
1485
+ const T = StringSet({}) // Pass options if any
1467
1486
 
1468
- type T = Static<typeof T> // type T = Vector
1487
+ const A = Value.Check(T, new Set()) // const A = true
1469
1488
 
1470
- const R1 = Value.Check(T, { x: 1, y: 1 }) // const R1 = true
1489
+ const B = Value.Check(T, new Set(['hello'])) // const B = true
1471
1490
 
1472
- const R2 = Value.Check(T, { x: 1, y: '1' }) // const R2 = false
1491
+ const C = Value.Check(T, new Set([1])) // const C = false
1473
1492
 
1474
- const R3 = Value.Check(T, { x: 1, y: -1 }) // const R3 = false
1475
1493
  ```
1476
1494
 
1477
1495
  <a name='typesystem-formats'></a>
1478
1496
 
1479
1497
  ### Formats
1480
1498
 
1481
- Use the `Format(...)` function to create a custom string format. The following creates a format that checks for lowercase strings.
1499
+ Use the TypeSystem Format function to register a string format.
1482
1500
 
1483
1501
  ```typescript
1484
- TypeSystem.Format('lowercase', value => value === value.toLowerCase()) // format should be lowercase
1502
+ import { TypeSystem } from '@sinclair/typebox/system'
1503
+
1504
+ const F = TypeSystem.Format('foo', value => value === 'Foo')
1485
1505
 
1486
- const T = Type.String({ format: 'lowercase' })
1506
+ const T = Type.String({ format: F })
1487
1507
 
1488
- const A = Value.Check(T, 'Hello') // const A = false
1508
+ const A = Value.Check(T, 'foo') // const A = true
1489
1509
 
1490
- const B = Value.Check(T, 'hello') // const B = true
1510
+ const B = Value.Check(T, 'bar') // const B = false
1511
+ ```
1512
+
1513
+ <a name='typesystem-errors'></a>
1514
+
1515
+ ### Errors
1516
+
1517
+ Use the TypeSystemErrorFunction module to override validation error message generation. This can be used to localize error messages or create custom errors for custom types.
1518
+
1519
+ ```typescript
1520
+ import { TypeSystemErrorFunction, ValueErrorType, DefaultErrorFunction } from '@sinclair/typebox/system'
1521
+
1522
+ TypeSystemErrorFunction.Set((schema, errorType) => {// i18n override
1523
+ switch(errorType) {
1524
+ /* en-US */ case ValueErrorType.String: return 'Expected string'
1525
+ /* fr-FR */ case ValueErrorType.Number: return 'Nombre attendu'
1526
+ /* ko-KR */ case ValueErrorType.Boolean: return '예상 부울'
1527
+ /* en-US */ default: return DefaultErrorFunction(schema, errorType)
1528
+ }
1529
+ })
1530
+ const T = Type.Object({ // const T = { ... }
1531
+ x: Type.String(),
1532
+ y: Type.Number(),
1533
+ z: Type.Boolean()
1534
+ })
1535
+ const E = [...Value.Errors(T, { // const E = [{
1536
+ x: null, // type: 48,
1537
+ y: null, // schema: { ... },
1538
+ z: null // path: '/x',
1539
+ })] // value: null,
1540
+ // message: 'Expected string'
1541
+ // }, {
1542
+ // type: 34,
1543
+ // schema: { ... },
1544
+ // path: '/y',
1545
+ // value: null,
1546
+ // message: 'Nombre attendu'
1547
+ // }, {
1548
+ // type: 14,
1549
+ // schema: { ... },
1550
+ // path: '/z',
1551
+ // value: null,
1552
+ // message: '예상 부울'
1553
+ // }]
1491
1554
  ```
1492
1555
 
1493
1556
  <a name='typesystem-policies'></a>
1494
1557
 
1495
1558
  ### Policies
1496
1559
 
1497
- TypeBox validates using standard JSON Schema assertion policies by default. It is possible to override some of these policies to have TypeBox assert inline with TypeScript static assertion rules. The following policy overrides are available.
1560
+ TypeBox type checks using standard Json Schema assertion policies by default. The TypeSystemPolicy module can override some of these policies to have TypeBox check inline with TypeScript static assertions. It also provides overrides for certain checking policies related to non-serializable values (such as void) which can be useful in Json based protocols such as JsonRpc-2.
1561
+
1562
+ The following overrides are available.
1498
1563
 
1499
1564
  ```typescript
1565
+ import { TypeSystemPolicy } from '@sinclair/typebox/system'
1566
+
1500
1567
  // Disallow undefined values for optional properties (default is false)
1501
1568
  //
1502
1569
  // const A: { x?: number } = { x: undefined } - disallowed when enabled
1503
1570
 
1504
- TypeSystem.ExactOptionalPropertyTypes = true
1571
+ TypeSystemPolicy.ExactOptionalPropertyTypes = true
1505
1572
 
1506
1573
  // Allow arrays to validate as object types (default is false)
1507
1574
  //
1508
1575
  // const A: {} = [] - allowed in TS
1509
1576
 
1510
- TypeSystem.AllowArrayObjects = true
1577
+ TypeSystemPolicy.AllowArrayObject = true
1511
1578
 
1512
1579
  // Allow numeric values to be NaN or + or - Infinity (default is false)
1513
1580
  //
1514
1581
  // const A: number = NaN - allowed in TS
1515
1582
 
1516
- TypeSystem.AllowNaN = true
1583
+ TypeSystemPolicy.AllowNaN = true
1584
+
1585
+ // Allow void type to check with undefined and null (default is false)
1586
+ //
1587
+ // Used to signal void return on Json-RPC 2.0 protocol
1588
+
1589
+ TypeSystemPolicy.AllowNullVoid = true
1517
1590
  ```
1518
1591
 
1519
1592
  <a name='workbench'></a>
1520
1593
 
1521
1594
  ## TypeBox Workbench
1522
1595
 
1523
- TypeBox offers a small web based code generation tool that can be used to convert TypeScript types into TypeBox types as well as a variety of other runtime type representations.
1596
+ TypeBox offers a web based code generation tool that can convert TypeScript types into TypeBox types as well as several other ecosystem libraries.
1524
1597
 
1525
1598
  [TypeBox Workbench Link Here](https://sinclairzx81.github.io/typebox-workbench/)
1526
1599
 
1600
+ <a name='codegen'></a>
1601
+
1602
+ ## TypeBox Codegen
1603
+
1604
+ TypeBox provides an auxilary code generation library that can be used to automate type translation between TypeScript and TypeBox types. This library also includes functionality to transform other ecosystem libraries.
1605
+
1606
+ [TypeBox Codegen Link Here](https://github.com/sinclairzx81/typebox-codegen)
1607
+
1527
1608
  <a name='ecosystem'></a>
1528
1609
 
1529
1610
  ## Ecosystem
1530
1611
 
1531
- The following is a list of community packages that provide general tooling and framework integration support for TypeBox.
1612
+ The following list is a set of community packages that offer general tooling, extended functionality and framework integration support for TypeBox.
1532
1613
 
1533
1614
  | Package | Description |
1534
1615
  | ------------- | ------------- |
@@ -1536,7 +1617,7 @@ The following is a list of community packages that provide general tooling and f
1536
1617
  | [fastify-type-provider-typebox](https://github.com/fastify/fastify-type-provider-typebox) | Fastify TypeBox integration with the Fastify Type Provider |
1537
1618
  | [feathersjs](https://github.com/feathersjs/feathers) | The API and real-time application framework |
1538
1619
  | [fetch-typebox](https://github.com/erfanium/fetch-typebox) | Drop-in replacement for fetch that brings easy integration with TypeBox |
1539
- | [schema2typebox](https://github.com/xddq/schema2typebox) | Creating TypeBox code from JSON schemas |
1620
+ | [schema2typebox](https://github.com/xddq/schema2typebox) | Creating TypeBox code from Json Schemas |
1540
1621
  | [ts2typebox](https://github.com/xddq/ts2typebox) | Creating TypeBox code from Typescript types |
1541
1622
  | [typebox-client](https://github.com/flodlc/typebox-client) | Type safe http client library for Fastify |
1542
1623
  | [typebox-validators](https://github.com/jtlapp/typebox-validators) | Advanced validators supporting discriminated and heterogeneous unions |
@@ -1559,35 +1640,35 @@ This benchmark measures compilation performance for varying types. You can revie
1559
1640
  ┌────────────────────────────┬────────────┬──────────────┬──────────────┬──────────────┐
1560
1641
  │ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │
1561
1642
  ├────────────────────────────┼────────────┼──────────────┼──────────────┼──────────────┤
1562
- │ Literal_String │ 1000 │ ' 232 ms' │ ' 8 ms' │ ' 29.00 x' │
1563
- │ Literal_Number │ 1000 │ ' 179 ms' │ ' 6 ms' │ ' 29.83 x' │
1564
- │ Literal_Boolean │ 1000 │ ' 154 ms' │ ' 3 ms' │ ' 51.33 x' │
1565
- │ Primitive_Number │ 1000 │ ' 160 ms' │ ' 7 ms' │ ' 22.86 x' │
1566
- │ Primitive_String │ 1000 │ ' 149 ms' │ ' 6 ms' │ ' 24.83 x' │
1567
- │ Primitive_String_Pattern │ 1000 │ ' 191 ms' │ ' 9 ms' │ ' 21.22 x' │
1568
- │ Primitive_Boolean │ 1000 │ ' 135 ms' │ ' 4 ms' │ ' 33.75 x' │
1569
- │ Primitive_Null │ 1000 │ ' 144 ms' │ ' 6 ms' │ ' 24.00 x' │
1570
- │ Object_Unconstrained │ 1000 │ ' 1144 ms' │ ' 30 ms' │ ' 38.13 x' │
1571
- │ Object_Constrained │ 1000 │ ' 1228 ms' │ ' 24 ms' │ ' 51.17 x' │
1572
- │ Object_Vector3 │ 1000 │ ' 380 ms' │ ' 9 ms' │ ' 42.22 x' │
1573
- │ Object_Box3D │ 1000 │ ' 1771 ms' │ ' 30 ms' │ ' 59.03 x' │
1574
- │ Tuple_Primitive │ 1000 │ ' 471 ms' │ ' 11 ms' │ ' 42.82 x' │
1575
- │ Tuple_Object │ 1000 │ ' 1272 ms' │ ' 15 ms' │ ' 84.80 x' │
1576
- │ Composite_Intersect │ 1000 │ ' 606 ms' │ ' 17 ms' │ ' 35.65 x' │
1577
- │ Composite_Union │ 1000 │ ' 560 ms' │ ' 22 ms' │ ' 25.45 x' │
1578
- │ Math_Vector4 │ 1000 │ ' 824 ms' │ ' 14 ms' │ ' 58.86 x' │
1579
- │ Math_Matrix4 │ 1000 │ ' 419 ms' │ ' 9 ms' │ ' 46.56 x' │
1580
- │ Array_Primitive_Number │ 1000 │ ' 382 ms' │ ' 6 ms' │ ' 63.67 x' │
1581
- │ Array_Primitive_String │ 1000 │ ' 324 ms' │ ' 6 ms' │ ' 54.00 x' │
1582
- │ Array_Primitive_Boolean │ 1000 │ ' 301 ms' │ ' 4 ms' │ ' 75.25 x' │
1583
- │ Array_Object_Unconstrained │ 1000 │ ' 1734 ms' │ ' 21 ms' │ ' 82.57 x' │
1584
- │ Array_Object_Constrained │ 1000 │ ' 1509 ms' │ ' 20 ms' │ ' 75.45 x' │
1585
- │ Array_Tuple_Primitive │ 1000 │ ' 824 ms' │ ' 14 ms' │ ' 58.86 x' │
1586
- │ Array_Tuple_Object │ 1000 │ ' 1619 ms' │ ' 16 ms' │ ' 101.19 x' │
1587
- │ Array_Composite_Intersect │ 1000 │ ' 773 ms' │ ' 16 ms' │ ' 48.31 x' │
1588
- │ Array_Composite_Union │ 1000 │ ' 822 ms' │ ' 17 ms' │ ' 48.35 x' │
1589
- │ Array_Math_Vector4 │ 1000 │ ' 1131 ms' │ ' 13 ms' │ ' 87.00 x' │
1590
- │ Array_Math_Matrix4 │ 1000 │ ' 661 ms' │ ' 10 ms' │ ' 66.10 x' │
1643
+ │ Literal_String │ 1000 │ ' 216 ms' │ ' 9 ms' │ ' 24.00 x' │
1644
+ │ Literal_Number │ 1000 │ ' 169 ms' │ ' 7 ms' │ ' 24.14 x' │
1645
+ │ Literal_Boolean │ 1000 │ ' 150 ms' │ ' 5 ms' │ ' 30.00 x' │
1646
+ │ Primitive_Number │ 1000 │ ' 161 ms' │ ' 7 ms' │ ' 23.00 x' │
1647
+ │ Primitive_String │ 1000 │ ' 148 ms' │ ' 6 ms' │ ' 24.67 x' │
1648
+ │ Primitive_String_Pattern │ 1000 │ ' 185 ms' │ ' 9 ms' │ ' 20.56 x' │
1649
+ │ Primitive_Boolean │ 1000 │ ' 132 ms' │ ' 4 ms' │ ' 33.00 x' │
1650
+ │ Primitive_Null │ 1000 │ ' 141 ms' │ ' 3 ms' │ ' 47.00 x' │
1651
+ │ Object_Unconstrained │ 1000 │ ' 1109 ms' │ ' 30 ms' │ ' 36.97 x' │
1652
+ │ Object_Constrained │ 1000 │ ' 1200 ms' │ ' 24 ms' │ ' 50.00 x' │
1653
+ │ Object_Vector3 │ 1000 │ ' 379 ms' │ ' 9 ms' │ ' 42.11 x' │
1654
+ │ Object_Box3D │ 1000 │ ' 1709 ms' │ ' 30 ms' │ ' 56.97 x' │
1655
+ │ Tuple_Primitive │ 1000 │ ' 456 ms' │ ' 14 ms' │ ' 32.57 x' │
1656
+ │ Tuple_Object │ 1000 │ ' 1229 ms' │ ' 17 ms' │ ' 72.29 x' │
1657
+ │ Composite_Intersect │ 1000 │ ' 570 ms' │ ' 17 ms' │ ' 33.53 x' │
1658
+ │ Composite_Union │ 1000 │ ' 513 ms' │ ' 19 ms' │ ' 27.00 x' │
1659
+ │ Math_Vector4 │ 1000 │ ' 782 ms' │ ' 13 ms' │ ' 60.15 x' │
1660
+ │ Math_Matrix4 │ 1000 │ ' 393 ms' │ ' 12 ms' │ ' 32.75 x' │
1661
+ │ Array_Primitive_Number │ 1000 │ ' 361 ms' │ ' 12 ms' │ ' 30.08 x' │
1662
+ │ Array_Primitive_String │ 1000 │ ' 296 ms' │ ' 5 ms' │ ' 59.20 x' │
1663
+ │ Array_Primitive_Boolean │ 1000 │ ' 315 ms' │ ' 4 ms' │ ' 78.75 x' │
1664
+ │ Array_Object_Unconstrained │ 1000 │ ' 1721 ms' │ ' 22 ms' │ ' 78.23 x' │
1665
+ │ Array_Object_Constrained │ 1000 │ ' 1450 ms' │ ' 21 ms' │ ' 69.05 x' │
1666
+ │ Array_Tuple_Primitive │ 1000 │ ' 813 ms' │ ' 13 ms' │ ' 62.54 x' │
1667
+ │ Array_Tuple_Object │ 1000 │ ' 1537 ms' │ ' 17 ms' │ ' 90.41 x' │
1668
+ │ Array_Composite_Intersect │ 1000 │ ' 753 ms' │ ' 17 ms' │ ' 44.29 x' │
1669
+ │ Array_Composite_Union │ 1000 │ ' 808 ms' │ ' 16 ms' │ ' 50.50 x' │
1670
+ │ Array_Math_Vector4 │ 1000 │ ' 1118 ms' │ ' 16 ms' │ ' 69.88 x' │
1671
+ │ Array_Math_Matrix4 │ 1000 │ ' 690 ms' │ ' 9 ms' │ ' 76.67 x' │
1591
1672
  └────────────────────────────┴────────────┴──────────────┴──────────────┴──────────────┘
1592
1673
  ```
1593
1674
 
@@ -1601,37 +1682,37 @@ This benchmark measures validation performance for varying types. You can review
1601
1682
  ┌────────────────────────────┬────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
1602
1683
  │ (index) │ Iterations │ ValueCheck │ Ajv │ TypeCompiler │ Performance │
1603
1684
  ├────────────────────────────┼────────────┼──────────────┼──────────────┼──────────────┼──────────────┤
1604
- │ Literal_String │ 1000000 │ ' 18 ms' │ ' 5 ms' │ ' 4 ms' │ ' 1.25 x' │
1605
- │ Literal_Number │ 1000000 │ ' 15 ms' │ ' 18 ms' │ ' 9 ms' │ ' 2.00 x' │
1606
- │ Literal_Boolean │ 1000000 │ ' 13 ms' │ ' 16 ms' │ ' 9 ms' │ ' 1.78 x' │
1607
- │ Primitive_Number │ 1000000 │ ' 21 ms' │ ' 16 ms' │ ' 9 ms' │ ' 1.78 x' │
1608
- │ Primitive_String │ 1000000 │ ' 19 ms' │ ' 16 ms' │ ' 10 ms' │ ' 1.60 x' │
1609
- │ Primitive_String_Pattern │ 1000000 │ ' 150 ms' │ ' 41 ms' │ ' 35 ms' │ ' 1.17 x' │
1610
- │ Primitive_Boolean │ 1000000 │ ' 17 ms' │ ' 17 ms' │ ' 9 ms' │ ' 1.89 x' │
1611
- │ Primitive_Null │ 1000000 │ ' 18 ms' │ ' 16 ms' │ ' 9 ms' │ ' 1.78 x' │
1612
- │ Object_Unconstrained │ 1000000 │ ' 1001 ms' │ ' 31 ms' │ ' 24 ms' │ ' 1.29 x' │
1613
- │ Object_Constrained │ 1000000 │ ' 1288 ms' │ ' 50 ms' │ ' 36 ms' │ ' 1.39 x' │
1614
- │ Object_Vector3 │ 1000000 │ ' 439 ms' │ ' 23 ms' │ ' 14 ms' │ ' 1.64 x' │
1615
- │ Object_Box3D │ 1000000 │ ' 2109 ms' │ ' 52 ms' │ ' 45 ms' │ ' 1.16 x' │
1616
- │ Object_Recursive │ 1000000 │ ' 5337 ms' │ ' 356 ms' │ ' 162 ms' │ ' 2.20 x' │
1617
- │ Tuple_Primitive │ 1000000 │ ' 164 ms' │ ' 21 ms' │ ' 13 ms' │ ' 1.62 x' │
1618
- │ Tuple_Object │ 1000000 │ ' 744 ms' │ ' 29 ms' │ ' 18 ms' │ ' 1.61 x' │
1619
- │ Composite_Intersect │ 1000000 │ ' 764 ms' │ ' 23 ms' │ ' 14 ms' │ ' 1.64 x' │
1620
- │ Composite_Union │ 1000000 │ ' 516 ms' │ ' 23 ms' │ ' 13 ms' │ ' 1.77 x' │
1621
- │ Math_Vector4 │ 1000000 │ ' 262 ms' │ ' 20 ms' │ ' 11 ms' │ ' 1.82 x' │
1622
- │ Math_Matrix4 │ 1000000 │ ' 1089 ms' │ ' 37 ms' │ ' 27 ms' │ ' 1.37 x' │
1623
- │ Array_Primitive_Number │ 1000000 │ ' 276 ms' │ ' 21 ms' │ ' 11 ms' │ ' 1.91 x' │
1624
- │ Array_Primitive_String │ 1000000 │ ' 228 ms' │ ' 21 ms' │ ' 14 ms' │ ' 1.50 x' │
1625
- │ Array_Primitive_Boolean │ 1000000 │ ' 159 ms' │ ' 21 ms' │ ' 13 ms' │ ' 1.62 x' │
1626
- │ Array_Object_Unconstrained │ 1000000 │ ' 5695 ms' │ ' 77 ms' │ ' 69 ms' │ ' 1.12 x' │
1627
- │ Array_Object_Constrained │ 1000000 │ ' 5701 ms' │ ' 127 ms' │ ' 110 ms' │ ' 1.15 x' │
1628
- │ Array_Object_Recursive │ 1000000 │ ' 21267 ms' │ ' 1664 ms' │ ' 573 ms' │ ' 2.90 x' │
1629
- │ Array_Tuple_Primitive │ 1000000 │ ' 702 ms' │ ' 40 ms' │ ' 32 ms' │ ' 1.25 x' │
1630
- │ Array_Tuple_Object │ 1000000 │ ' 3141 ms' │ ' 68 ms' │ ' 51 ms' │ ' 1.33 x' │
1631
- │ Array_Composite_Intersect │ 1000000 │ ' 3145 ms' │ ' 44 ms' │ ' 35 ms' │ ' 1.26 x' │
1632
- │ Array_Composite_Union │ 1000000 │ ' 2134 ms' │ ' 68 ms' │ ' 31 ms' │ ' 2.19 x' │
1633
- │ Array_Math_Vector4 │ 1000000 │ ' 1197 ms' │ ' 37 ms' │ ' 25 ms' │ ' 1.48 x' │
1634
- │ Array_Math_Matrix4 │ 1000000 │ ' 5323 ms' │ ' 111 ms' │ ' 96 ms' │ ' 1.16 x' │
1685
+ │ Literal_String │ 1000000 │ ' 24 ms' │ ' 5 ms' │ ' 4 ms' │ ' 1.25 x' │
1686
+ │ Literal_Number │ 1000000 │ ' 15 ms' │ ' 20 ms' │ ' 10 ms' │ ' 2.00 x' │
1687
+ │ Literal_Boolean │ 1000000 │ ' 14 ms' │ ' 19 ms' │ ' 9 ms' │ ' 2.11 x' │
1688
+ │ Primitive_Number │ 1000000 │ ' 25 ms' │ ' 18 ms' │ ' 10 ms' │ ' 1.80 x' │
1689
+ │ Primitive_String │ 1000000 │ ' 21 ms' │ ' 24 ms' │ ' 9 ms' │ ' 2.67 x' │
1690
+ │ Primitive_String_Pattern │ 1000000 │ ' 156 ms' │ ' 43 ms' │ ' 38 ms' │ ' 1.13 x' │
1691
+ │ Primitive_Boolean │ 1000000 │ ' 18 ms' │ ' 17 ms' │ ' 9 ms' │ ' 1.89 x' │
1692
+ │ Primitive_Null │ 1000000 │ ' 20 ms' │ ' 17 ms' │ ' 9 ms' │ ' 1.89 x' │
1693
+ │ Object_Unconstrained │ 1000000 │ ' 1055 ms' │ ' 32 ms' │ ' 24 ms' │ ' 1.33 x' │
1694
+ │ Object_Constrained │ 1000000 │ ' 1232 ms' │ ' 49 ms' │ ' 43 ms' │ ' 1.14 x' │
1695
+ │ Object_Vector3 │ 1000000 │ ' 432 ms' │ ' 23 ms' │ ' 13 ms' │ ' 1.77 x' │
1696
+ │ Object_Box3D │ 1000000 │ ' 1993 ms' │ ' 54 ms' │ ' 46 ms' │ ' 1.17 x' │
1697
+ │ Object_Recursive │ 1000000 │ ' 5115 ms' │ ' 342 ms' │ ' 159 ms' │ ' 2.15 x' │
1698
+ │ Tuple_Primitive │ 1000000 │ ' 156 ms' │ ' 21 ms' │ ' 13 ms' │ ' 1.62 x' │
1699
+ │ Tuple_Object │ 1000000 │ ' 740 ms' │ ' 29 ms' │ ' 18 ms' │ ' 1.61 x' │
1700
+ │ Composite_Intersect │ 1000000 │ ' 797 ms' │ ' 26 ms' │ ' 14 ms' │ ' 1.86 x' │
1701
+ │ Composite_Union │ 1000000 │ ' 530 ms' │ ' 23 ms' │ ' 13 ms' │ ' 1.77 x' │
1702
+ │ Math_Vector4 │ 1000000 │ ' 240 ms' │ ' 22 ms' │ ' 11 ms' │ ' 2.00 x' │
1703
+ │ Math_Matrix4 │ 1000000 │ ' 1036 ms' │ ' 39 ms' │ ' 27 ms' │ ' 1.44 x' │
1704
+ │ Array_Primitive_Number │ 1000000 │ ' 248 ms' │ ' 20 ms' │ ' 12 ms' │ ' 1.67 x' │
1705
+ │ Array_Primitive_String │ 1000000 │ ' 227 ms' │ ' 22 ms' │ ' 13 ms' │ ' 1.69 x' │
1706
+ │ Array_Primitive_Boolean │ 1000000 │ ' 138 ms' │ ' 21 ms' │ ' 13 ms' │ ' 1.62 x' │
1707
+ │ Array_Object_Unconstrained │ 1000000 │ ' 5540 ms' │ ' 66 ms' │ ' 59 ms' │ ' 1.12 x' │
1708
+ │ Array_Object_Constrained │ 1000000 │ ' 5750 ms' │ ' 123 ms' │ ' 108 ms' │ ' 1.14 x' │
1709
+ │ Array_Object_Recursive │ 1000000 │ ' 21842 ms' │ ' 1771 ms' │ ' 599 ms' │ ' 2.96 x' │
1710
+ │ Array_Tuple_Primitive │ 1000000 │ ' 715 ms' │ ' 36 ms' │ ' 29 ms' │ ' 1.24 x' │
1711
+ │ Array_Tuple_Object │ 1000000 │ ' 3131 ms' │ ' 63 ms' │ ' 50 ms' │ ' 1.26 x' │
1712
+ │ Array_Composite_Intersect │ 1000000 │ ' 3064 ms' │ ' 44 ms' │ ' 35 ms' │ ' 1.26 x' │
1713
+ │ Array_Composite_Union │ 1000000 │ ' 2172 ms' │ ' 65 ms' │ ' 31 ms' │ ' 2.10 x' │
1714
+ │ Array_Math_Vector4 │ 1000000 │ ' 1032 ms' │ ' 37 ms' │ ' 24 ms' │ ' 1.54 x' │
1715
+ │ Array_Math_Matrix4 │ 1000000 │ ' 4859 ms' │ ' 114 ms' │ ' 86 ms' │ ' 1.33 x' │
1635
1716
  └────────────────────────────┴────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
1636
1717
  ```
1637
1718
 
@@ -1645,11 +1726,11 @@ The following table lists esbuild compiled and minified sizes for each TypeBox m
1645
1726
  ┌──────────────────────┬────────────┬────────────┬─────────────┐
1646
1727
  │ (index) │ Compiled │ Minified │ Compression │
1647
1728
  ├──────────────────────┼────────────┼────────────┼─────────────┤
1648
- │ typebox/compiler │ '131.4 kb' │ ' 59.4 kb' │ '2.21 x' │
1649
- │ typebox/errors │ '113.6 kb' │ ' 50.9 kb' │ '2.23 x' │
1650
- │ typebox/system │ ' 78.5 kb' │ ' 32.5 kb' │ '2.42 x' │
1651
- │ typebox/value │ '182.8 kb' │ ' 80.0 kb' │ '2.28 x' │
1652
- │ typebox │ ' 77.4 kb' │ ' 32.0 kb' │ '2.42 x' │
1729
+ │ typebox/compiler │ '148.9 kb' │ ' 65.8 kb' │ '2.26 x' │
1730
+ │ typebox/errors │ '111.5 kb' │ ' 49.1 kb' │ '2.27 x' │
1731
+ │ typebox/system │ ' 82.6 kb' │ ' 36.8 kb' │ '2.24 x' │
1732
+ │ typebox/value │ '190.5 kb' │ ' 82.4 kb' │ '2.31 x' │
1733
+ │ typebox │ ' 72.4 kb' │ ' 31.6 kb' │ '2.29 x' │
1653
1734
  └──────────────────────┴────────────┴────────────┴─────────────┘
1654
1735
  ```
1655
1736