@sinclair/typebox 0.25.23 → 0.26.0-dev

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.
Files changed (44) hide show
  1. package/compiler/compiler.d.ts +9 -4
  2. package/compiler/compiler.js +160 -119
  3. package/errors/errors.d.ts +56 -46
  4. package/errors/errors.js +234 -149
  5. package/package.json +1 -6
  6. package/readme.md +395 -396
  7. package/system/system.d.ts +9 -6
  8. package/system/system.js +17 -17
  9. package/typebox.d.ts +386 -162
  10. package/typebox.js +1710 -229
  11. package/value/cast.d.ts +2 -2
  12. package/value/cast.js +120 -192
  13. package/value/check.d.ts +1 -1
  14. package/value/check.js +162 -107
  15. package/value/convert.d.ts +13 -0
  16. package/value/convert.js +345 -0
  17. package/value/create.d.ts +6 -2
  18. package/value/create.js +149 -107
  19. package/{hash → value}/hash.js +39 -14
  20. package/value/index.d.ts +1 -0
  21. package/value/index.js +3 -1
  22. package/value/value.d.ts +2 -8
  23. package/value/value.js +20 -14
  24. package/conditional/conditional.d.ts +0 -17
  25. package/conditional/conditional.js +0 -91
  26. package/conditional/index.d.ts +0 -2
  27. package/conditional/index.js +0 -45
  28. package/conditional/structural.d.ts +0 -11
  29. package/conditional/structural.js +0 -685
  30. package/custom/custom.d.ts +0 -12
  31. package/custom/custom.js +0 -55
  32. package/custom/index.d.ts +0 -1
  33. package/custom/index.js +0 -44
  34. package/format/format.d.ts +0 -12
  35. package/format/format.js +0 -55
  36. package/format/index.d.ts +0 -1
  37. package/format/index.js +0 -44
  38. package/guard/guard.d.ts +0 -60
  39. package/guard/guard.js +0 -440
  40. package/guard/index.d.ts +0 -1
  41. package/guard/index.js +0 -44
  42. package/hash/index.d.ts +0 -1
  43. package/hash/index.js +0 -44
  44. /package/{hash → value}/hash.d.ts +0 -0
package/readme.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  <p>JSON Schema Type Builder with Static Type Resolution for TypeScript</p>
6
6
 
7
- <img src="https://github.com/sinclairzx81/typebox/blob/master/typebox.png?raw=true" />
7
+ <img src="./typebox.png" />
8
8
 
9
9
  <br />
10
10
  <br />
@@ -19,23 +19,23 @@
19
19
 
20
20
  ## Install
21
21
 
22
- ### npm
22
+ #### Npm
23
23
  ```bash
24
24
  $ npm install @sinclair/typebox --save
25
25
  ```
26
26
 
27
- ### deno
27
+ #### Deno
28
28
  ```typescript
29
29
  import { Static, Type } from 'npm:@sinclair/typebox'
30
30
  ```
31
31
 
32
- ### esm
32
+ #### Esm
33
33
 
34
34
  ```typescript
35
35
  import { Static, Type } from 'https://esm.sh/@sinclair/typebox'
36
36
  ```
37
37
 
38
- ## Usage
38
+ ## Example
39
39
 
40
40
  ```typescript
41
41
  import { Static, Type } from '@sinclair/typebox'
@@ -62,32 +62,33 @@ type T = Static<typeof T> // type T = {
62
62
 
63
63
  ## Overview
64
64
 
65
- TypeBox is a type builder library that creates in-memory JSON Schema objects that can be statically inferred as TypeScript types. The schemas produced by this library are designed to match the static type checking rules of the TypeScript compiler. TypeBox enables one to create a unified type that can be statically checked by TypeScript and runtime asserted using standard JSON Schema validation.
65
+ TypeBox is a runtime type builder that constructs in-memory JSON Schema objects that can be statically inferred as TypeScript types. The schemas produced by this library are designed to match the static type checking rules of the TypeScript compiler. TypeBox enables one to create a unified type that can be statically checked by TypeScript and runtime asserted using standard JSON Schema validation.
66
66
 
67
- TypeBox is designed to enable JSON schema to compose with the same flexibility as TypeScript's type system. It can be used either as a simple tool to build up complex schemas or integrated into REST and RPC services to help validate data received over the wire.
67
+ 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 and RPC services to help validate data received over the wire.
68
68
 
69
69
  License MIT
70
70
 
71
71
  ## Contents
72
72
  - [Install](#install)
73
73
  - [Overview](#overview)
74
- - [Example](#Example)
74
+ - [Usage](#usage)
75
75
  - [Types](#types)
76
76
  - [Standard](#types-standard)
77
77
  - [Extended](#types-extended)
78
78
  - [Modifiers](#types-modifiers)
79
79
  - [Options](#types-options)
80
- - [Reference](#types-reference)
80
+ - [Generics](#types-generics)
81
+ - [References](#types-references)
81
82
  - [Recursive](#types-recursive)
82
- - [Generic](#types-generic)
83
83
  - [Conditional](#types-conditional)
84
- - [Unsafe](#types-unsafe)
85
84
  - [Guards](#types-guards)
85
+ - [Unsafe](#types-unsafe)
86
86
  - [Strict](#types-strict)
87
87
  - [Values](#values)
88
88
  - [Create](#values-create)
89
89
  - [Clone](#values-clone)
90
90
  - [Check](#values-check)
91
+ - [Convert](#values-convert)
91
92
  - [Cast](#values-cast)
92
93
  - [Equal](#values-equal)
93
94
  - [Hash](#values-hash)
@@ -96,25 +97,25 @@ License MIT
96
97
  - [Errors](#values-errors)
97
98
  - [Pointer](#values-pointer)
98
99
  - [TypeCheck](#typecheck)
99
- - [TypeCompiler](#typecheck-typecompiler)
100
100
  - [Ajv](#typecheck-ajv)
101
+ - [TypeCompiler](#typecheck-typecompiler)
101
102
  - [TypeSystem](#typecheck)
102
103
  - [Types](#typesystem-types)
103
104
  - [Formats](#typesystem-formats)
105
+ - [Policies](#typesystem-policies)
104
106
  - [Benchmark](#benchmark)
105
107
  - [Compile](#benchmark-compile)
106
108
  - [Validate](#benchmark-validate)
107
109
  - [Compression](#benchmark-compression)
108
110
  - [Contribute](#contribute)
109
111
 
110
- <a name="Example"></a>
112
+ <a name="usage"></a>
111
113
 
112
- ## Example
114
+ ## Usage
113
115
 
114
- The following demonstrates TypeBox's general usage.
116
+ The following shows general usage.
115
117
 
116
118
  ```typescript
117
-
118
119
  import { Static, Type } from '@sinclair/typebox'
119
120
 
120
121
  //--------------------------------------------------------------------------------------------
@@ -173,9 +174,11 @@ type T = Static<typeof T> // type T = {
173
174
  //
174
175
  //--------------------------------------------------------------------------------------------
175
176
 
176
- function receive(value: T) { // ... as a Type
177
+ import { Value } from '@sinclair/typebox/value'
178
+
179
+ function receive(value: T) { // ... as a Static Type
177
180
 
178
- if(JSON.validate(T, value)) { // ... as a Schema
181
+ if(Value.Check(T, value)) { // ... as a JSON Schema
179
182
 
180
183
  // ok...
181
184
  }
@@ -186,13 +189,13 @@ function receive(value: T) { // ... as a Type
186
189
 
187
190
  ## Types
188
191
 
189
- TypeBox provides a set of functions that allow you to compose JSON Schema similar to how you would compose static types with TypeScript. Each function creates a JSON schema fragment which can compose into more complex types. The schemas produced by TypeBox can be passed directly to any JSON Schema compliant validator, or used to reflect runtime metadata for a type.
192
+ TypeBox types are small JSON schema fragments which can compose into more complex types though function composition. Each fragment is strictly defined to match to the static type checking rules of TypeScript. TypeBox provides a Standard type set which produces standards compliant JSON schema as well as an Extended type set used to define native JavaScript constructs.
190
193
 
191
194
  <a name='types-standard'></a>
192
195
 
193
- ### Standard
196
+ ### Standard Types
194
197
 
195
- The following table lists the Standard TypeBox types.
198
+ The following table lists the Standard TypeBox types. These types are fully compatible with the JSON Schema specification.
196
199
 
197
200
  ```typescript
198
201
  ┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
@@ -230,12 +233,6 @@ The following table lists the Standard TypeBox types.
230
233
  │ │ │ } │
231
234
  │ │ │ │
232
235
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
233
- │ const T = Type.RegEx(/foo/) │ type T = string │ const T = { │
234
- │ │ │ type: 'string', │
235
- │ │ │ pattern: 'foo' │
236
- │ │ │ } │
237
- │ │ │ │
238
- ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
239
236
  │ const T = Type.Literal(42) │ type T = 42 │ const T = { │
240
237
  │ │ │ const: 42, │
241
238
  │ │ │ type: 'number' │
@@ -252,15 +249,14 @@ The following table lists the Standard TypeBox types.
252
249
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
253
250
  │ const T = Type.Object({ │ type T = { │ const T = { │
254
251
  │ x: Type.Number(), │ x: number, │ type: 'object', │
255
- │ y: Type.Number() │ y: number │ properties: {
256
- │ }) │ } │ x: {
257
- │ │ │ type: 'number'
258
- │ │ │ },
259
- │ │ │ y: {
260
- │ │ │ type: 'number'
261
- │ │ │ }
262
- │ │ │ },
263
- │ │ │ required: ['x', 'y'] │
252
+ │ y: Type.Number() │ y: number │ required: ['x', 'y'],
253
+ │ }) │ } │ properties: {
254
+ │ │ │ x: {
255
+ │ │ │ type: 'number'
256
+ │ │ │ }, {
257
+ │ │ │ type: 'number'
258
+ │ │ │ }
259
+ │ │ │ }
264
260
  │ │ │ } │
265
261
  │ │ │ │
266
262
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
@@ -310,13 +306,36 @@ The following table lists the Standard TypeBox types.
310
306
  │ │ │ │
311
307
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
312
308
  │ const T = Type.Intersect([ │ type T = { │ const T = { │
313
- │ Type.Object({ │ x: number │ type: 'object',
314
- │ x: Type.Number() │ } & { │ properties: {
315
- │ }), │ y: number │ x: {
316
- │ Type.Object({ │ } │ type: 'number'
317
- │ y: Type.Number() │ │ },
318
- }) │ │ y: {
319
- │ ]) │ │ type: 'number'
309
+ │ Type.Object({ │ x: number │ allOf: [{
310
+ │ x: Type.Number() │ } & { │ type: 'object',
311
+ │ }), │ y: number │ required: ['x'],
312
+ │ Type.Object({ │ } │ properties: {
313
+ │ y: Type.Number() │ │ x: {
314
+ ]) │ │ type: 'number'
315
+ │ ]) │ │ }
316
+ │ │ │ } │
317
+ │ │ │ }, { │
318
+ │ │ │ type: 'object', |
319
+ │ │ │ required: ['y'], │
320
+ │ │ │ properties: { │
321
+ │ │ │ y: { │
322
+ │ │ │ type: 'number' │
323
+ │ │ │ } │
324
+ │ │ │ }] │
325
+ │ │ │ } │
326
+ │ │ │ │
327
+ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
328
+ │ const T = Type.Composite([ │ type T = { │ const T = { │
329
+ │ Type.Object({ │ x: number | string │ type: 'object', │
330
+ │ x: Type.Number() │ y: number │ properties: { │
331
+ │ }), │ } │ x: { │
332
+ │ Type.Object({ │ │ anyOf: [ │
333
+ │ x: Type.String() │ │ { type: 'number' }, │
334
+ │ y: Type.Number() │ │ { type: 'string' } │
335
+ │ }) │ │ ] │
336
+ │ ]) │ │ }, │
337
+ │ │ │ y: { │
338
+ │ │ │ type: 'number' │
320
339
  │ │ │ } │
321
340
  │ │ │ }, │
322
341
  │ │ │ required: ['x', 'y'] │
@@ -334,6 +353,47 @@ The following table lists the Standard TypeBox types.
334
353
  │ │ │ } │
335
354
  │ │ │ │
336
355
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
356
+ │ const T = Type.Not( | type T = string │ const T = { │
357
+ | Type.Union([ │ │ allOf: [{ │
358
+ │ Type.Literal('x'), │ │ not: { │
359
+ │ Type.Literal('y'), │ │ anyOf: [ │
360
+ │ Type.Literal('z') │ │ { const: 'x' }, │
361
+ │ ]), │ │ { const: 'y' }, │
362
+ │ Type.String() │ │ { const: 'z' } │
363
+ │ ) │ │ ] │
364
+ │ │ │ } │
365
+ │ │ │ }, { │
366
+ │ │ │ type: 'string' │
367
+ │ │ │ }] │
368
+ │ │ │ } │
369
+ │ │ │ │
370
+ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
371
+ │ const T = Type.Extends( │ type T = │ const T = { │
372
+ │ Type.String(), │ string extends number │ const: false, │
373
+ │ Type.Number(), │ true : false │ type: 'boolean' │
374
+ │ Type.Literal(true), │ │ } │
375
+ │ Type.Literal(false) │ │ │
376
+ │ ) │ │ │
377
+ │ │ │ │
378
+ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
379
+ │ const T = Type.Extract( │ type T = Extract< │ const T = { │
380
+ │ Type.Union([ │ string | number, │ type: 'string' │
381
+ │ Type.String(), │ string │ } │
382
+ │ Type.Number(), │ > │ │
383
+ │ ]), │ │ │
384
+ │ Type.String() │ │ │
385
+ │ ) │ │ │
386
+ │ │ │ │
387
+ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
388
+ │ const T = Type.Exclude( │ type T = Exclude< │ const T = { │
389
+ │ Type.Union([ │ string | number, │ type: 'number' │
390
+ │ Type.String(), │ string │ } │
391
+ │ Type.Number(), │ > │ │
392
+ │ ]), │ │ │
393
+ │ Type.String() │ │ │
394
+ │ ) │ │ │
395
+ │ │ │ │
396
+ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
337
397
  │ const T = Type.Record( │ type T = Record< │ const T = { │
338
398
  │ Type.String(), │ string, │ type: 'object', │
339
399
  │ Type.Number() │ number, │ patternProperties: { │
@@ -359,15 +419,15 @@ The following table lists the Standard TypeBox types.
359
419
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
360
420
  │ const T = Type.Required( │ type T = Required<{ │ const T = { │
361
421
  │ Type.Object({ │ x?: number, │ type: 'object', │
362
- │ x: Type.Optional( │ y?: number │ properties: {
363
- │ Type.Number() | }> │ x: {
364
- │ ), │ │ type: 'number'
365
- │ y: Type.Optional( │ │ },
366
- │ Type.Number() │ │ y: {
367
- │ ) │ │ type: 'number'
368
- │ }) │ │ }
369
- │ ) │ │ },
370
- │ │ │ required: ['x', 'y']
422
+ │ x: Type.Optional( │ y?: number │ required: ['x', 'y'],
423
+ │ Type.Number() | }> │ properties: {
424
+ │ ), │ │ x: {
425
+ │ y: Type.Optional( │ │ type: 'number'
426
+ │ Type.Number() │ │ },
427
+ │ ) │ │ y: {
428
+ │ }) │ │ type: 'number'
429
+ │ ) │ │ }
430
+ │ │ │ }
371
431
  │ │ │ } │
372
432
  │ │ │ │
373
433
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
@@ -392,14 +452,38 @@ The following table lists the Standard TypeBox types.
392
452
  │ │ │ required: ['y'] │
393
453
  │ │ │ } │
394
454
  │ │ │ │
455
+ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
456
+ │ const A = Type.Object({ │ type A = { │ const T = { │
457
+ │ x: Type.Number(), │ x: number, │ $ref: 'A' │
458
+ │ y: Type.Number() │ y: number │ } │
459
+ │ }, { $id: 'T' }) | } │ │
460
+ │ │ │ │
461
+ │ const T = Type.Ref(A) │ type T = A │ │
462
+ │ │ │ │
463
+ │ │ │ │
464
+ │ │ │ │
465
+ │ │ │ │
466
+ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
467
+ │ const A = Type.Object({ │ type T = { │ const T = { │
468
+ │ x: Type.Number(), │ x: number, │ $id: 'T' │
469
+ │ y: Type.Number() │ y: number │ type: 'object', │
470
+ │ }, { $id: 'T' }) | } │ required: ['x', 'y'], │
471
+ │ │ │ properties: { │
472
+ │ const T = Type.Deref( │ │ x: { type: 'number' }, │
473
+ │ Type.Ref(A) │ │ y: { type: 'number' }, │
474
+ │ ) │ │ } │
475
+ │ │ │ } │
476
+ │ │ │ │
395
477
  └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
396
478
  ```
397
479
 
398
480
  <a name='types-extended'></a>
399
481
 
400
- ### Extended
482
+ ### Extended Types
401
483
 
402
- TypeBox provides a set of extended types that can be used to express schematics for core JavaScript constructs and primitives. Extended types are not valid JSON Schema and will not validate using typical validation. These types however can be used to frame JSON schema and describe callable RPC interfaces that may receive JSON validated data.
484
+ TypeBox provides several extended types that can be used to produce schematics for common JavaScript constructs. These types cannot 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.
485
+
486
+ The following lists the supported types
403
487
 
404
488
  ```typescript
405
489
  ┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
@@ -462,6 +546,24 @@ TypeBox provides a set of extended types that can be used to express schematics
462
546
  │ │ │ } │
463
547
  │ │ │ │
464
548
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
549
+ │ const T = Type.RegEx(/foo/) │ type T = string │ const T = { │
550
+ │ │ │ type: 'string', │
551
+ │ │ │ pattern: 'foo' │
552
+ │ │ │ } │
553
+ │ │ │ │
554
+ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
555
+ │ const T = Type.Symbol() │ type T = symbol │ const T = { │
556
+ │ │ │ type: 'null', │
557
+ │ │ │ typeOf: 'Symbol' │
558
+ │ │ │ } │
559
+ │ │ │ │
560
+ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
561
+ │ const T = Type.BigInt() │ type T = bigint │ const T = { │
562
+ │ │ │ type: 'null', │
563
+ │ │ │ typeOf: 'BigInt' │
564
+ │ │ │ } │
565
+ │ │ │ │
566
+ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
465
567
  │ const T = Type.Void() │ type T = void │ const T = { │
466
568
  │ │ │ type: 'null' │
467
569
  │ │ │ typeOf: 'Void' │
@@ -474,7 +576,7 @@ TypeBox provides a set of extended types that can be used to express schematics
474
576
 
475
577
  ### Modifiers
476
578
 
477
- TypeBox provides modifiers that can be applied to an objects properties. This allows for `optional` and `readonly` to be applied to that property. The following table illustates how they map between TypeScript and JSON Schema.
579
+ TypeBox provides property modifier types that allow properties to be mapped with TypeScript `readonly` and `optional`. The following table shows the modifier types and how they map between TypeScript and JSON Schema.
478
580
 
479
581
  ```typescript
480
582
  ┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
@@ -518,24 +620,69 @@ TypeBox provides modifiers that can be applied to an objects properties. This al
518
620
 
519
621
  ### Options
520
622
 
521
- You can pass additional JSON schema options on the last argument of any given type. The following are some examples.
623
+ You can pass JSON Schema compliant options on the last argument of any type. Option property hints are provided for convenience.
522
624
 
523
625
  ```typescript
524
- // string must be an email
525
- const T = Type.String({ format: 'email' })
626
+ // String must be an email
627
+ const T = Type.String({ // const T = {
628
+ format: 'email' // type: 'string',
629
+ }) // format: 'email'
630
+ // }
526
631
 
527
- // number must be a multiple of 2
528
- const T = Type.Number({ multipleOf: 2 })
632
+ // Mumber must be a multiple of 2
633
+ const T = Type.Number({ // const T = {
634
+ multipleOf: 2 // type: 'number',
635
+ }) // multipleOf: 2
636
+ // }
637
+
638
+ // 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
+ // }
529
646
 
530
- // array must have at least 5 integer values
531
- const T = Type.Array(Type.Integer(), { minItems: 5 })
532
647
  ```
533
648
 
534
- <a name='types-reference'></a>
649
+ <a name='types-generics'></a>
535
650
 
536
- ### Reference
651
+ ### Generic Types
537
652
 
538
- Use `Type.Ref(...)` to create referenced types. The target type must specify an `$id`.
653
+ Generic types can be created with generic functions. The following creates a generic `Vector<T>` type.
654
+
655
+ ```typescript
656
+ import { Type, Static, TSchema } from '@sinclair/typebox'
657
+
658
+ const Vector = <T extends TSchema>(t: T) => Type.Object({ x: t, y: t, z: t })
659
+
660
+ const NumberVector = Vector(Type.Number()) // const NumberVector = {
661
+ // type: 'object',
662
+ // required: ['x', 'y', 'z'],
663
+ // properties: {
664
+ // x: { type: 'number' },
665
+ // y: { type: 'number' },
666
+ // z: { type: 'number' }
667
+ // }
668
+ // }
669
+
670
+ const BooleanVector = Vector(Type.Boolean()) // const BooleanVector = {
671
+ // type: 'object',
672
+ // required: ['x', 'y', 'z'],
673
+ // properties: {
674
+ // x: { type: 'boolean' },
675
+ // y: { type: 'boolean' },
676
+ // z: { type: 'boolean' }
677
+ // }
678
+ // }
679
+ ```
680
+
681
+ <a name='types-references'></a>
682
+
683
+ ### Reference Types
684
+
685
+ Reference types are supported with `Type.Ref(...)`. Use `Type.Deref(...)` to dereference a type.
539
686
 
540
687
  ```typescript
541
688
  const T = Type.String({ $id: 'T' }) // const T = {
@@ -546,13 +693,18 @@ const T = Type.String({ $id: 'T' }) // const T = {
546
693
  const R = Type.Ref(T) // const R = {
547
694
  // $ref: 'T'
548
695
  // }
696
+
697
+ const U = Type.Deref(R) // const U = {
698
+ // $id: 'T',
699
+ // type: 'string'
700
+ // }
549
701
  ```
550
702
 
551
703
  <a name='types-recursive'></a>
552
704
 
553
- ### Recursive
705
+ ### Recursive Types
554
706
 
555
- Use `Type.Recursive(...)` to create recursive types.
707
+ Recursive types are supported with `Type.Recursive(...)`.
556
708
 
557
709
  ```typescript
558
710
  const Node = Type.Recursive(Node => Type.Object({ // const Node = {
@@ -581,95 +733,34 @@ type Node = Static<typeof Node> // type Node = {
581
733
  // }
582
734
 
583
735
  function test(node: Node) {
584
- const id = node.nodes[0].nodes[0] // id is string
585
- .nodes[0].nodes[0]
586
- .id
736
+ const id = node.nodes[0].nodes[0].id // id is string
587
737
  }
588
738
  ```
589
739
 
590
- <a name='types-generic'></a>
591
-
592
- ### Generic
593
-
594
- Use functions to create generic types. The following creates a generic `Nullable<T>` type.
595
-
596
- ```typescript
597
- import { Type, Static, TSchema } from '@sinclair/typebox'
598
-
599
- const Nullable = <T extends TSchema>(type: T) => Type.Union([type, Type.Null()])
600
-
601
- const T = Nullable(Type.String()) // const T = {
602
- // anyOf: [{
603
- // type: 'string'
604
- // }, {
605
- // type: 'null'
606
- // }]
607
- // }
608
-
609
- type T = Static<typeof T> // type T = string | null
610
-
611
- const U = Nullable(Type.Number()) // const U = {
612
- // anyOf: [{
613
- // type: 'number'
614
- // }, {
615
- // type: 'null'
616
- // }]
617
- // }
618
-
619
- type U = Static<typeof U> // type U = number | null
620
- ```
621
-
622
740
  <a name='types-conditional'></a>
623
741
 
624
- ### Conditional
742
+ ### Conditional Types
625
743
 
626
- Use the conditional module to create [Conditional Types](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html). This module implements TypeScript's structural equivalence checks to enable TypeBox types to be conditionally inferred at runtime. This module also provides the [Extract](https://www.typescriptlang.org/docs/handbook/utility-types.html#extracttype-union) and [Exclude](https://www.typescriptlang.org/docs/handbook/utility-types.html#excludeuniontype-excludedmembers) utility types which are expressed as conditional types in TypeScript.
744
+ Conditional types are supported with `Extends`, `Exclude` and `Extract`. These work the same as in TypeScript.
627
745
 
628
- The conditional module is provided as an optional import.
746
+ #### TypeScript
629
747
 
630
748
  ```typescript
631
- import { Conditional } from '@sinclair/typebox/conditional'
749
+ type T0 = string extends number ? true : false
750
+ // ^ false
751
+ type T1 = Extract<string | number, number>
752
+ // ^ number
753
+ type T2 = Exclude<string | number, number>
754
+ // ^ string
632
755
  ```
633
- The following table shows the TypeBox mappings between TypeScript and JSON schema.
634
-
756
+ #### TypeBox
635
757
  ```typescript
636
- ┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
637
- TypeBox │ TypeScript │ JSON Schema │
638
- │ │ │ │
639
- ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
640
- const T = Conditional.Extends( type T = │ const T = { │
641
- │ Type.String(), │ string extends number │ const: false, │
642
- │ Type.Number(), │ true : false │ type: 'boolean' │
643
- │ Type.Literal(true), │ │ } │
644
- │ Type.Literal(false) │ │ │
645
- │ ) │ │ │
646
- │ │ │ │
647
- ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
648
- │ const T = Conditional.Extract( │ type T = Extract< │ const T = { │
649
- │ Type.Union([ │ 'a' | 'b' | 'c', │ anyOf: [{ │
650
- │ Type.Literal('a'), │ 'a' | 'f' │ const: 'a' │
651
- │ Type.Literal('b'), │ > │ type: 'string' │
652
- │ Type.Literal('c') │ │ }] │
653
- │ ]), │ │ } │
654
- │ Type.Union([ │ │ │
655
- │ Type.Literal('a'), │ │ │
656
- │ Type.Literal('f') │ │ │
657
- │ ]) │ │ │
658
- │ ) │ │ │
659
- │ │ │ │
660
- ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
661
- │ const T = Conditional.Exclude( │ type T = Exclude< │ const T = { │
662
- │ Type.Union([ │ 'a' | 'b' | 'c', │ anyOf: [{ │
663
- │ Type.Literal('a'), │ 'a' │ const: 'b', │
664
- │ Type.Literal('b'), │ > │ type: 'string' │
665
- │ Type.Literal('c') │ │ }, { │
666
- │ ]), │ │ const: 'c', │
667
- │ Type.Union([ │ │ type: 'string' │
668
- │ Type.Literal('a') │ │ }] │
669
- │ ]) │ │ } │
670
- │ ) │ │ │
671
- │ │ │ │
672
- └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
758
+ const T0 = Type.Extends(Type.String(), Type.Number(), Type.Literal(true), Type.Literal(false))
759
+ // ^ TLiteral<false>
760
+ const T1 = Type.Extract(Type.Union([Type.String(), Type.Number()]), Type.Number())
761
+ // ^ TNumber
762
+ const T2 = Type.Exclude(Type.Union([Type.String(), Type.Number()]), Type.Number())
763
+ // ^ TString<string>
673
764
  ```
674
765
 
675
766
  <a name='types-unsafe'></a>
@@ -686,16 +777,12 @@ const T = Type.Unsafe<string>({ type: 'number' }) // const T = {
686
777
  type T = Static<typeof T> // type T = string
687
778
  ```
688
779
 
689
- This function can be used to create custom schemas for validators that require specific schema representations. An example of this might be OpenAPI's `nullable` and `enum` schemas which are not provided by TypeBox. The following demonstrates using `Type.Unsafe(...)` to create these types.
780
+ The `Type.Unsafe(...)` type allows specific or non-standard OpenAPI schematics can be constructed.
690
781
 
691
782
  ```typescript
692
783
  import { Type, Static, TSchema } from '@sinclair/typebox'
693
784
 
694
- //--------------------------------------------------------------------------------------------
695
- //
696
785
  // Nullable<T>
697
- //
698
- //--------------------------------------------------------------------------------------------
699
786
 
700
787
  function Nullable<T extends TSchema>(schema: T) {
701
788
  return Type.Unsafe<Static<T> | null>({ ...schema, nullable: true })
@@ -708,12 +795,7 @@ const T = Nullable(Type.String()) // const T = {
708
795
 
709
796
  type T = Static<typeof T> // type T = string | null
710
797
 
711
-
712
- //--------------------------------------------------------------------------------------------
713
- //
714
798
  // StringEnum<string[]>
715
- //
716
- //--------------------------------------------------------------------------------------------
717
799
 
718
800
  function StringEnum<T extends string[]>(values: [...T]) {
719
801
  return Type.Unsafe<T[number]>({ type: 'string', enum: values })
@@ -730,10 +812,10 @@ type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
730
812
 
731
813
  ### Guards
732
814
 
733
- Use the guard module to test if values are TypeBox types.
815
+ TypeBox provides a `TypeGuard` module used for type value assertions and reflection.
734
816
 
735
817
  ```typescript
736
- import { TypeGuard } from '@sinclair/typebox/guard'
818
+ import { Type, TypeGuard } from '@sinclair/typebox'
737
819
 
738
820
  const T = Type.String()
739
821
 
@@ -747,7 +829,7 @@ if(TypeGuard.TString(T)) {
747
829
 
748
830
  ### Strict
749
831
 
750
- TypeBox schemas contain the `Kind` and `Modifier` symbol properties. These properties are provided to enable runtime type reflection on schemas, as well as helping TypeBox internally compose types. These properties are not strictly valid JSON schema; so in some cases it may be desirable to omit them. TypeBox provides a `Type.Strict()` function that will omit these properties if necessary.
832
+ TypeBox schemas contain the `Kind` and `Modifier` symbol properties. These properties are used for type composition and runtime type reflection. These properties are not strictly valid JSON schema; so in some cases it may be desirable to omit them. TypeBox provides a `Type.Strict()` function that will omit these properties if necessary.
751
833
 
752
834
  ```typescript
753
835
  const T = Type.Object({ // const T = {
@@ -776,7 +858,7 @@ const U = Type.Strict(T) // const U = {
776
858
 
777
859
  ## Values
778
860
 
779
- TypeBox includes an optional values module that can be used to perform common operations on JavaScript values. This module enables one to create, check and cast values from types. It also provides functionality to check equality, clone and diff and patch JavaScript values. The value module is provided as an optional import.
861
+ 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 additional import.
780
862
 
781
863
  ```typescript
782
864
  import { Value } from '@sinclair/typebox/value'
@@ -786,7 +868,7 @@ import { Value } from '@sinclair/typebox/value'
786
868
 
787
869
  ### Create
788
870
 
789
- Use the Create function to create a value from a TypeBox type. TypeBox will use default values if specified.
871
+ Use the Create function to create a value from a type. TypeBox will use default values if specified.
790
872
 
791
873
  ```typescript
792
874
  const T = Type.Object({ x: Type.Number(), y: Type.Number({ default: 42 }) })
@@ -816,6 +898,20 @@ const T = Type.Object({ x: Type.Number() })
816
898
  const R = Value.Check(T, { x: 1 }) // const R = true
817
899
  ```
818
900
 
901
+ <a name='values-convert'></a>
902
+
903
+ ### Convert
904
+
905
+ Use the Convert function to convert a value into its target type if a reasonable conversion is possible.
906
+
907
+ ```typescript
908
+ const T = Type.Object({ x: Type.Number(), y: Type.Number() })
909
+
910
+ const R1 = Value.Convert(T, { x: '3.14' }) // const R1 = { x: 3.14 }
911
+
912
+ const R2 = Value.Convert(T, { x: 'not a number' }) // const R2 = { x: 'not a number' }
913
+ ```
914
+
819
915
  <a name='values-cast'></a>
820
916
 
821
917
  ### Cast
@@ -918,7 +1014,7 @@ const R = [...Value.Errors(T, { x: '42' })] // const R = [{
918
1014
 
919
1015
  ### Pointer
920
1016
 
921
- Use ValuePointer to perform mutable updates on existing values using [RFC6901](https://www.rfc-editor.org/rfc/rfc6901) Json Pointers.
1017
+ Use ValuePointer to perform mutable updates on existing values using [RFC6901](https://www.rfc-editor.org/rfc/rfc6901) JSON Pointers.
922
1018
 
923
1019
  ```typescript
924
1020
  import { ValuePointer } from '@sinclair/typebox/value'
@@ -933,17 +1029,58 @@ ValuePointer.Set(A, '/z', 1) // const A = { x: 1, y: 1,
933
1029
 
934
1030
  ## TypeCheck
935
1031
 
936
- TypeBox targets JSON Schema Draft 6 and is built and tested against the Ajv JSON Schema validator for standards compliance. TypeBox also includes an optional built-in TypeCompiler that can provide improved compilation and validation performance specifically for TypeBox types only.
1032
+ TypeBox types targets JSON Schema draft 6 so is immediately 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.
1033
+
1034
+ The following details using both Ajv and TypeBox's compiler infrastructure.
1035
+
1036
+ <a name='typecheck-ajv'></a>
1037
+
1038
+ ## Ajv
1039
+
1040
+ The following shows the recommended setup for Ajv with additional string formats.
1041
+
1042
+ ```bash
1043
+ $ npm install ajv ajv-formats --save
1044
+ ```
1045
+
1046
+ ```typescript
1047
+ import { Type } from '@sinclair/typebox'
1048
+ import addFormats from 'ajv-formats'
1049
+ import Ajv from 'ajv'
937
1050
 
938
- The following sections detail using these validators.
1051
+ const ajv = addFormats(new Ajv({}), [
1052
+ 'date-time',
1053
+ 'time',
1054
+ 'date',
1055
+ 'email',
1056
+ 'hostname',
1057
+ 'ipv4',
1058
+ 'ipv6',
1059
+ 'uri',
1060
+ 'uri-reference',
1061
+ 'uuid',
1062
+ 'uri-template',
1063
+ 'json-pointer',
1064
+ 'relative-json-pointer',
1065
+ 'regex'
1066
+ ])
1067
+
1068
+ const C = ajv.compile(Type.Object({
1069
+ x: Type.Number(),
1070
+ y: Type.Number(),
1071
+ z: Type.Number()
1072
+ }))
1073
+
1074
+ const R = C({ x: 1, y: 2, z: 3 }) // const R = true
1075
+ ```
939
1076
 
940
1077
  <a name='typecheck-typecompiler'></a>
941
1078
 
942
1079
  ### TypeCompiler
943
1080
 
944
- TypeBox includes an high performance just-in-time (JIT) compiler and type checker that can be used in applications that require extremely fast validation. Note that this compiler is optimized for TypeBox types only where the schematics are known in advance.
1081
+ The TypeBox TypeCompiler is a high performance JIT compiler that compiles TypeBox types into optimized JavaScript validation routines. The compiler is tuned both for fast compilation and value assertion. It is designed primarily for integrating into application frameworks but can also be used as a general purpose validator.
945
1082
 
946
- The compiler module is provided as an optional import.
1083
+ The TypeCompiler is provided as an optional import.
947
1084
 
948
1085
  ```typescript
949
1086
  import { TypeCompiler } from '@sinclair/typebox/compiler'
@@ -961,7 +1098,7 @@ const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObje
961
1098
  const R = C.Check({ x: 1, y: 2, z: 3 }) // const R = true
962
1099
  ```
963
1100
 
964
- Validation errors can be read with the `Errors(...)` function.
1101
+ Use the `Errors(...)` function to produce diagnostics for a value. The `Errors(...)` function will return an iterator that will perform an exhaustive check across the value and yield any error found. For performance, this function should only be called after failed `Check(...)`.
965
1102
 
966
1103
  ```typescript
967
1104
  const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObject<{
@@ -1002,217 +1139,78 @@ console.log(C.Code()) // return function check(va
1002
1139
  // }
1003
1140
  ```
1004
1141
 
1005
- <a name='typecheck-ajv'></a>
1006
-
1007
- ### Ajv
1008
-
1009
- The following are the recommended configurations to support both the [Standard](#standard) and [Extended](#extended) type sets provided by TypeBox. For schema portability and publishing to remote systems, it is recommended to use the Standard type set only.
1142
+ <a name='typesystem'></a>
1010
1143
 
1011
- ```bash
1012
- $ npm install ajv ajv-formats --save
1013
- ```
1144
+ ## TypeSystem
1014
1145
 
1015
- <details>
1146
+ The TypeBox TypeSystem module provides functionality to define types above and beyond the Standard and Extended type sets as well as control various assertion polices. Configurations made to the TypeSystem module are observed by both `TypeCompiler` and `Value` modules.
1016
1147
 
1017
- <summary>
1018
- <strong>Standard Ajv Configuration</strong>
1019
- <p>Expand for Standard Type Set Configuration</p>
1020
- </summary>
1148
+ The TypeSystem module is provided as an optional import.
1021
1149
 
1022
1150
  ```typescript
1023
- import { Type } from '@sinclair/typebox'
1024
- import addFormats from 'ajv-formats'
1025
- import Ajv from 'ajv'
1026
-
1027
- export function createAjv() {
1028
- return addFormats(new Ajv({}), [
1029
- 'date-time',
1030
- 'time',
1031
- 'date',
1032
- 'email',
1033
- 'hostname',
1034
- 'ipv4',
1035
- 'ipv6',
1036
- 'uri',
1037
- 'uri-reference',
1038
- 'uuid',
1039
- 'uri-template',
1040
- 'json-pointer',
1041
- 'relative-json-pointer',
1042
- 'regex'
1043
- ])
1044
- }
1045
-
1046
- const ajv = createAjv()
1047
-
1048
- const R = ajv.validate(Type.Object({ // const R = true
1049
- x: Type.Number(),
1050
- y: Type.Number(),
1051
- z: Type.Number()
1052
- }), { x: 1, y: 2, z: 3 })
1151
+ import { TypeSystem } from '@sinclair/typebox/system'
1053
1152
  ```
1054
1153
 
1055
- </details>
1154
+ <a name='typesystem-types'></a>
1056
1155
 
1057
- <details>
1156
+ ### Types
1058
1157
 
1059
- <summary>
1060
- <strong>Extended Ajv Configuration</strong>
1061
- <p>Expand for Extended Type Set Configuration</p>
1062
- </summary>
1158
+ Use the `Type(...)` function to create a custom type. This function will return a type factory function that can be used to construct the type. The following creates a Point type.
1063
1159
 
1064
1160
  ```typescript
1065
- import { TypeGuard } from '@sinclair/typebox/guard'
1066
- import { Value } from '@sinclair/typebox/value'
1067
- import { Type } from '@sinclair/typebox'
1068
- import addFormats from 'ajv-formats'
1069
- import Ajv from 'ajv'
1070
-
1071
- function schemaOf(schemaOf: string, value: unknown, schema: unknown) {
1072
- switch (schemaOf) {
1073
- case 'Constructor':
1074
- return TypeGuard.TConstructor(schema) && Value.Check(schema, value) // not supported
1075
- case 'Function':
1076
- return TypeGuard.TFunction(schema) && Value.Check(schema, value) // not supported
1077
- case 'Date':
1078
- return TypeGuard.TDate(schema) && Value.Check(schema, value)
1079
- case 'Promise':
1080
- return TypeGuard.TPromise(schema) && Value.Check(schema, value) // not supported
1081
- case 'Uint8Array':
1082
- return TypeGuard.TUint8Array(schema) && Value.Check(schema, value)
1083
- case 'Undefined':
1084
- return TypeGuard.TUndefined(schema) && Value.Check(schema, value) // not supported
1085
- case 'Void':
1086
- return TypeGuard.TVoid(schema) && Value.Check(schema, value)
1087
- default:
1088
- return false
1089
- }
1090
- }
1091
-
1092
- export function createAjv() {
1093
- return addFormats(new Ajv({}), [
1094
- 'date-time',
1095
- 'time',
1096
- 'date',
1097
- 'email',
1098
- 'hostname',
1099
- 'ipv4',
1100
- 'ipv6',
1101
- 'uri',
1102
- 'uri-reference',
1103
- 'uuid',
1104
- 'uri-template',
1105
- 'json-pointer',
1106
- 'relative-json-pointer',
1107
- 'regex'
1108
- ])
1109
- .addKeyword({ type: 'object', keyword: 'instanceOf', validate: schemaOf })
1110
- .addKeyword({ type: 'null', keyword: 'typeOf', validate: schemaOf })
1111
- .addKeyword('exclusiveMinimumTimestamp')
1112
- .addKeyword('exclusiveMaximumTimestamp')
1113
- .addKeyword('minimumTimestamp')
1114
- .addKeyword('maximumTimestamp')
1115
- .addKeyword('minByteLength')
1116
- .addKeyword('maxByteLength')
1117
- }
1161
+ type PointOptions = { } // The Type Options
1118
1162
 
1119
- const ajv = createAjv()
1163
+ type PointType = { x: number, y: number } // The Static<T> Type
1120
1164
 
1121
- const R = ajv.validate(Type.Object({ // const R = true
1122
- buffer: Type.Uint8Array(),
1123
- date: Type.Date(),
1124
- void: Type.Void()
1125
- }), {
1126
- buffer: new Uint8Array(),
1127
- date: new Date(),
1128
- void: null
1165
+ const Point = TypeSystem.Type<PointType, PointOptions>('Point', (options, value) => {
1166
+ return (
1167
+ typeof value === 'object' && value !== null &&
1168
+ typeof value.x === 'number' &&
1169
+ typeof value.y === 'number'
1170
+ )
1129
1171
  })
1130
- ```
1131
1172
 
1132
- </details>
1173
+ const T = Point()
1133
1174
 
1175
+ type T = Static<typeof T> // type T = { x: number, y: number }
1134
1176
 
1135
- <a name='typesystem'></a>
1136
-
1137
- ## TypeSystem
1138
-
1139
- TypeBox provides an extensible TypeSystem module that enables developers to register additional types above and beyond the standard or extended type set. This module also allows developers to define custom string formats as well as override certain type checking behaviours.
1140
-
1141
- The TypeSystem module is provided as an optional import.
1142
-
1143
- ```typescript
1144
- import { TypeSystem } from '@sinclair/typebox/system'
1177
+ const R = Value.Check(T, { x: 1, y: 2 }) // const R = true
1145
1178
  ```
1146
1179
 
1147
- <a name='typesystem-types'></a>
1180
+ <a name='typesystem-formats'></a>
1148
1181
 
1149
- ### Types
1182
+ ### Formats
1150
1183
 
1151
- Use the `CreateType(...)` function to specify and return a custom type. This function will return a type factory function that can be used to construct the type. The following creates and registers a BigNumber type which will statically infer as `bigint`.
1184
+ Use the `Format(...)` function to create a custom string formats. The following creates a custom string format that checks for lowercase strings.
1152
1185
 
1153
1186
  ```typescript
1154
- //--------------------------------------------------------------------------------------------
1155
- //
1156
- // Use TypeSystem.CreateType(...) to define and return a type factory function
1157
- //
1158
- //--------------------------------------------------------------------------------------------
1187
+ TypeSystem.Format('lowercase', value => value === value.toLowerCase()) // format should be lowercase
1159
1188
 
1160
- type BigNumberOptions = { minimum?: bigint; maximum?: bigint }
1161
-
1162
- const BigNumber = TypeSystem.CreateType<bigint, BigNumberOptions>(
1163
- 'BigNumber',
1164
- (options, value) => {
1165
- if (typeof value !== 'bigint') return false
1166
- if (options.maximum !== undefined && value > options.maximum) return false
1167
- if (options.minimum !== undefined && value < options.minimum) return false
1168
- return true
1169
- }
1170
- )
1171
-
1172
- //--------------------------------------------------------------------------------------------
1173
- //
1174
- // Use the custom type like any other type
1175
- //
1176
- //--------------------------------------------------------------------------------------------
1189
+ const T = Type.String({ format: 'lowercase' })
1177
1190
 
1178
- const T = BigNumber({ minimum: 10n, maximum: 20n }) // const T = {
1179
- // minimum: 10n,
1180
- // maximum: 20n,
1181
- // [Symbol(TypeBox.Kind)]: 'BigNumber'
1182
- // }
1191
+ const A = Value.Check(T, 'action') // const A = true
1183
1192
 
1184
- const C = TypeCompiler.Compile(T)
1185
- const X = C.Check(15n) // const X = true
1186
- const Y = C.Check(5n) // const Y = false
1187
- const Z = C.Check(25n) // const Z = false
1193
+ const B = Value.Check(T, 'ACTION') // const B = false
1188
1194
  ```
1189
1195
 
1190
- <a name='typesystem-formats'></a>
1196
+ <a name='typesystem-policies'></a>
1191
1197
 
1192
- ### Formats
1198
+ ### Policies
1193
1199
 
1194
- Use the `CreateFormat(...)` function to specify user defined string formats. The following creates a custom string format that checks for lowercase.
1200
+ TypeBox validates using JSON Schema assertion policies by default. It is possible to override these policies and have TypeBox assert using TypeScript policies. The following overrides are available.
1195
1201
 
1196
1202
  ```typescript
1197
- //--------------------------------------------------------------------------------------------
1203
+ // Allow arrays to validate as object types (default is false)
1198
1204
  //
1199
- // Use TypeSystem.CreateFormat(...) to define a custom string format
1200
- //
1201
- //--------------------------------------------------------------------------------------------
1205
+ // const A: {} = [] - allowed in TS
1202
1206
 
1203
- TypeSystem.CreateFormat('lowercase', value => value === value.toLowerCase())
1207
+ TypeSystem.AllowArrayObjects = true
1204
1208
 
1205
- //--------------------------------------------------------------------------------------------
1206
- //
1207
- // Use the format by creating string types with the 'format' option
1209
+ // Allow numeric values to be NaN or + or - Infinity (default is false)
1208
1210
  //
1209
- //--------------------------------------------------------------------------------------------
1210
-
1211
- const T = Type.String({ format: 'lowercase' })
1211
+ // const A: number = NaN - allowed in TS
1212
1212
 
1213
- const A = Value.Check(T, 'action') // const A = true
1214
-
1215
- const B = Value.Check(T, 'ACTION') // const B = false
1213
+ TypeSystem.AllowNaN = true
1216
1214
  ```
1217
1215
 
1218
1216
  <a name='benchmark'></a>
@@ -1233,29 +1231,29 @@ This benchmark measures compilation performance for varying types. You can revie
1233
1231
  ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┐
1234
1232
  │ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │
1235
1233
  ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┤
1236
- │ Number │ 2000 │ ' 418 ms' │ ' 14 ms' │ ' 29.86 x' │
1237
- │ String │ 2000 │ ' 331 ms' │ ' 12 ms' │ ' 27.58 x' │
1238
- │ Boolean │ 2000 │ ' 290 ms' │ ' 13 ms' │ ' 22.31 x' │
1239
- │ Null │ 2000 │ ' 253 ms' │ ' 8 ms' │ ' 31.63 x' │
1240
- │ RegEx │ 2000 │ ' 481 ms' │ ' 18 ms' │ ' 26.72 x' │
1241
- │ ObjectA │ 2000 │ ' 2675 ms' │ ' 54 ms' │ ' 49.54 x' │
1242
- │ ObjectB │ 2000 │ ' 2849 ms' │ ' 39 ms' │ ' 73.05 x' │
1243
- │ Tuple │ 2000 │ ' 1224 ms' │ ' 22 ms' │ ' 55.64 x' │
1244
- │ Union │ 2000 │ ' 1225 ms' │ ' 26 ms' │ ' 47.12 x' │
1245
- │ Vector4 │ 2000 │ ' 1777 ms' │ ' 24 ms' │ ' 74.04 x' │
1246
- │ Matrix4 │ 2000 │ ' 825 ms' │ ' 12 ms' │ ' 68.75 x' │
1247
- │ Literal_String │ 2000 │ ' 345 ms' │ ' 9 ms' │ ' 38.33 x' │
1248
- │ Literal_Number │ 2000 │ ' 363 ms' │ ' 7 ms' │ ' 51.86 x' │
1249
- │ Literal_Boolean │ 2000 │ ' 358 ms' │ ' 6 ms' │ ' 59.67 x' │
1250
- │ Array_Number │ 2000 │ ' 687 ms' │ ' 8 ms' │ ' 85.88 x' │
1251
- │ Array_String │ 2000 │ ' 726 ms' │ ' 8 ms' │ ' 90.75 x' │
1252
- │ Array_Boolean │ 2000 │ ' 703 ms' │ ' 8 ms' │ ' 87.88 x' │
1253
- │ Array_ObjectA │ 2000 │ ' 3686 ms' │ ' 40 ms' │ ' 92.15 x' │
1254
- │ Array_ObjectB │ 2000 │ ' 3821 ms' │ ' 40 ms' │ ' 95.53 x' │
1255
- │ Array_Tuple │ 2000 │ ' 2070 ms' │ ' 17 ms' │ ' 121.76 x' │
1256
- │ Array_Union │ 2000 │ ' 1503 ms' │ ' 21 ms' │ ' 71.57 x' │
1257
- │ Array_Vector4 │ 2000 │ ' 2185 ms' │ ' 21 ms' │ ' 104.05 x' │
1258
- │ Array_Matrix4 │ 2000 │ ' 1502 ms' │ ' 16 ms' │ ' 93.88 x' │
1234
+ │ Number │ 2000 │ ' 451 ms' │ ' 16 ms' │ ' 28.19 x' │
1235
+ │ String │ 2000 │ ' 338 ms' │ ' 14 ms' │ ' 24.14 x' │
1236
+ │ Boolean │ 2000 │ ' 297 ms' │ ' 13 ms' │ ' 22.85 x' │
1237
+ │ Null │ 2000 │ ' 265 ms' │ ' 8 ms' │ ' 33.13 x' │
1238
+ │ RegEx │ 2000 │ ' 492 ms' │ ' 18 ms' │ ' 27.33 x' │
1239
+ │ ObjectA │ 2000 │ ' 2744 ms' │ ' 55 ms' │ ' 49.89 x' │
1240
+ │ ObjectB │ 2000 │ ' 3005 ms' │ ' 44 ms' │ ' 68.30 x' │
1241
+ │ Tuple │ 2000 │ ' 1283 ms' │ ' 26 ms' │ ' 49.35 x' │
1242
+ │ Union │ 2000 │ ' 1263 ms' │ ' 27 ms' │ ' 46.78 x' │
1243
+ │ Vector4 │ 2000 │ ' 1622 ms' │ ' 23 ms' │ ' 70.52 x' │
1244
+ │ Matrix4 │ 2000 │ ' 888 ms' │ ' 12 ms' │ ' 74.00 x' │
1245
+ │ Literal_String │ 2000 │ ' 344 ms' │ ' 14 ms' │ ' 24.57 x' │
1246
+ │ Literal_Number │ 2000 │ ' 389 ms' │ ' 8 ms' │ ' 48.63 x' │
1247
+ │ Literal_Boolean │ 2000 │ ' 374 ms' │ ' 9 ms' │ ' 41.56 x' │
1248
+ │ Array_Number │ 2000 │ ' 710 ms' │ ' 12 ms' │ ' 59.17 x' │
1249
+ │ Array_String │ 2000 │ ' 739 ms' │ ' 9 ms' │ ' 82.11 x' │
1250
+ │ Array_Boolean │ 2000 │ ' 732 ms' │ ' 7 ms' │ ' 104.57 x' │
1251
+ │ Array_ObjectA │ 2000 │ ' 3733 ms' │ ' 42 ms' │ ' 88.88 x' │
1252
+ │ Array_ObjectB │ 2000 │ ' 3602 ms' │ ' 42 ms' │ ' 85.76 x' │
1253
+ │ Array_Tuple │ 2000 │ ' 2204 ms' │ ' 20 ms' │ ' 110.20 x' │
1254
+ │ Array_Union │ 2000 │ ' 1533 ms' │ ' 24 ms' │ ' 63.88 x' │
1255
+ │ Array_Vector4 │ 2000 │ ' 2263 ms' │ ' 21 ms' │ ' 107.76 x' │
1256
+ │ Array_Matrix4 │ 2000 │ ' 1576 ms' │ ' 14 ms' │ ' 112.57 x' │
1259
1257
  └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┘
1260
1258
  ```
1261
1259
 
@@ -1269,31 +1267,31 @@ This benchmark measures validation performance for varying types. You can review
1269
1267
  ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
1270
1268
  │ (index) │ Iterations │ ValueCheck │ Ajv │ TypeCompiler │ Performance │
1271
1269
  ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┼──────────────┤
1272
- │ Number │ 1000000 │ ' 28 ms' │ ' 6 ms' │ ' 6 ms' │ ' 1.00 x' │
1273
- │ String │ 1000000 │ ' 25 ms' │ ' 23 ms' │ ' 11 ms' │ ' 2.09 x' │
1274
- │ Boolean │ 1000000 │ ' 24 ms' │ ' 21 ms' │ ' 11 ms' │ ' 1.91 x' │
1275
- │ Null │ 1000000 │ ' 25 ms' │ ' 22 ms' │ ' 10 ms' │ ' 2.20 x' │
1276
- │ RegEx │ 1000000 │ ' 164 ms' │ ' 53 ms' │ ' 37 ms' │ ' 1.43 x' │
1277
- │ ObjectA │ 1000000 │ ' 593 ms' │ ' 47 ms' │ ' 25 ms' │ ' 1.88 x' │
1278
- │ ObjectB │ 1000000 │ ' 1053 ms' │ ' 54 ms' │ ' 40 ms' │ ' 1.35 x' │
1279
- │ Tuple │ 1000000 │ ' 129 ms' │ ' 25 ms' │ ' 16 ms' │ ' 1.56 x' │
1280
- │ Union │ 1000000 │ ' 334 ms' │ ' 25 ms' │ ' 16 ms' │ ' 1.56 x' │
1281
- │ Recursive │ 1000000 │ ' 3127 ms' │ ' 424 ms' │ ' 98 ms' │ ' 4.33 x' │
1282
- │ Vector4 │ 1000000 │ ' 152 ms' │ ' 24 ms' │ ' 12 ms' │ ' 2.00 x' │
1283
- │ Matrix4 │ 1000000 │ ' 593 ms' │ ' 41 ms' │ ' 27 ms' │ ' 1.52 x' │
1284
- │ Literal_String │ 1000000 │ ' 48 ms' │ ' 20 ms' │ ' 11 ms' │ ' 1.82 x' │
1285
- │ Literal_Number │ 1000000 │ ' 47 ms' │ ' 22 ms' │ ' 10 ms' │ ' 2.20 x' │
1286
- │ Literal_Boolean │ 1000000 │ ' 48 ms' │ ' 21 ms' │ ' 11 ms' │ ' 1.91 x' │
1287
- │ Array_Number │ 1000000 │ ' 495 ms' │ ' 32 ms' │ ' 21 ms' │ ' 1.52 x' │
1288
- │ Array_String │ 1000000 │ ' 481 ms' │ ' 31 ms' │ ' 21 ms' │ ' 1.48 x' │
1289
- │ Array_Boolean │ 1000000 │ ' 446 ms' │ ' 32 ms' │ ' 27 ms' │ ' 1.19 x' │
1290
- │ Array_ObjectA │ 1000000 │ ' 14314 ms' │ ' 2341 ms' │ ' 1969 ms' │ ' 1.19 x' │
1291
- │ Array_ObjectB │ 1000000 │ ' 16883 ms' │ ' 2661 ms' │ ' 2606 ms' │ ' 1.02 x' │
1292
- │ Array_Tuple │ 1000000 │ ' 1834 ms' │ ' 98 ms' │ ' 77 ms' │ ' 1.27 x' │
1293
- │ Array_Union │ 1000000 │ ' 4960 ms' │ ' 240 ms' │ ' 87 ms' │ ' 2.76 x' │
1294
- │ Array_Recursive │ 1000000 │ ' 56273 ms' │ ' 7118 ms' │ ' 1122 ms' │ ' 6.34 x' │
1295
- │ Array_Vector4 │ 1000000 │ ' 2498 ms' │ ' 99 ms' │ ' 48 ms' │ ' 2.06 x' │
1296
- │ Array_Matrix4 │ 1000000 │ ' 12487 ms' │ ' 383 ms' │ ' 246 ms' │ ' 1.56 x' │
1270
+ │ Number │ 1000000 │ ' 30 ms' │ ' 7 ms' │ ' 6 ms' │ ' 1.17 x' │
1271
+ │ String │ 1000000 │ ' 23 ms' │ ' 21 ms' │ ' 11 ms' │ ' 1.91 x' │
1272
+ │ Boolean │ 1000000 │ ' 22 ms' │ ' 21 ms' │ ' 10 ms' │ ' 2.10 x' │
1273
+ │ Null │ 1000000 │ ' 27 ms' │ ' 20 ms' │ ' 10 ms' │ ' 2.00 x' │
1274
+ │ RegEx │ 1000000 │ ' 163 ms' │ ' 47 ms' │ ' 38 ms' │ ' 1.24 x' │
1275
+ │ ObjectA │ 1000000 │ ' 654 ms' │ ' 41 ms' │ ' 24 ms' │ ' 1.71 x' │
1276
+ │ ObjectB │ 1000000 │ ' 1173 ms' │ ' 59 ms' │ ' 41 ms' │ ' 1.44 x' │
1277
+ │ Tuple │ 1000000 │ ' 124 ms' │ ' 24 ms' │ ' 17 ms' │ ' 1.41 x' │
1278
+ │ Union │ 1000000 │ ' 332 ms' │ ' 26 ms' │ ' 16 ms' │ ' 1.63 x' │
1279
+ │ Recursive │ 1000000 │ ' 3129 ms' │ ' 412 ms' │ ' 102 ms' │ ' 4.04 x' │
1280
+ │ Vector4 │ 1000000 │ ' 147 ms' │ ' 26 ms' │ ' 13 ms' │ ' 2.00 x' │
1281
+ │ Matrix4 │ 1000000 │ ' 576 ms' │ ' 41 ms' │ ' 28 ms' │ ' 1.46 x' │
1282
+ │ Literal_String │ 1000000 │ ' 51 ms' │ ' 21 ms' │ ' 10 ms' │ ' 2.10 x' │
1283
+ │ Literal_Number │ 1000000 │ ' 47 ms' │ ' 21 ms' │ ' 11 ms' │ ' 1.91 x' │
1284
+ │ Literal_Boolean │ 1000000 │ ' 47 ms' │ ' 21 ms' │ ' 10 ms' │ ' 2.10 x' │
1285
+ │ Array_Number │ 1000000 │ ' 490 ms' │ ' 33 ms' │ ' 18 ms' │ ' 1.83 x' │
1286
+ │ Array_String │ 1000000 │ ' 502 ms' │ ' 31 ms' │ ' 25 ms' │ ' 1.24 x' │
1287
+ │ Array_Boolean │ 1000000 │ ' 465 ms' │ ' 33 ms' │ ' 27 ms' │ ' 1.22 x' │
1288
+ │ Array_ObjectA │ 1000000 │ ' 15463 ms' │ ' 2470 ms' │ ' 2052 ms' │ ' 1.20 x' │
1289
+ │ Array_ObjectB │ 1000000 │ ' 18047 ms' │ ' 2497 ms' │ ' 2348 ms' │ ' 1.06 x' │
1290
+ │ Array_Tuple │ 1000000 │ ' 1958 ms' │ ' 99 ms' │ ' 77 ms' │ ' 1.29 x' │
1291
+ │ Array_Union │ 1000000 │ ' 5348 ms' │ ' 254 ms' │ ' 89 ms' │ ' 2.85 x' │
1292
+ │ Array_Recursive │ 1000000 │ ' 54643 ms' │ ' 8870 ms' │ ' 1158 ms' │ ' 7.66 x' │
1293
+ │ Array_Vector4 │ 1000000 │ ' 2724 ms' │ ' 105 ms' │ ' 48 ms' │ ' 2.19 x' │
1294
+ │ Array_Matrix4 │ 1000000 │ ' 13821 ms' │ ' 437 ms' │ ' 266 ms' │ ' 1.64 x' │
1297
1295
  └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
1298
1296
  ```
1299
1297
 
@@ -1307,14 +1305,15 @@ The following table lists esbuild compiled and minified sizes for each TypeBox m
1307
1305
  ┌──────────────────────┬────────────┬────────────┬─────────────┐
1308
1306
  │ (index) │ Compiled │ Minified │ Compression │
1309
1307
  ├──────────────────────┼────────────┼────────────┼─────────────┤
1310
- │ typebox/compiler │ ' 64 kb' │ ' 31 kb' │ '2.02 x' │
1311
- │ typebox/conditional │ ' 45 kb' │ ' 18 kb' │ '2.44 x' │
1312
- │ typebox/custom │ ' 0 kb' │ ' 0 kb' │ '2.61 x' │
1313
- │ typebox/format │ ' 0 kb' │ ' 0 kb' │ '2.66 x' │
1314
- │ typebox/guard │ ' 23 kb' │ ' 11 kb' │ '2.07 x' │
1315
- │ typebox/hash │ ' 4 kb' │ ' 1 kb' │ '2.30 x' │
1316
- │ typebox/value │ ' 89 kb' │ ' 41 kb' │ '2.15 x' │
1317
- │ typebox │ ' 12 kb' │ ' 6 kb' │ '1.89 x' │
1308
+ │ typebox/compiler │ ' 65.4 kb' │ ' 32.2 kb' │ '2.03 x' │
1309
+ │ typebox/conditional │ ' 45.5 kb' │ ' 18.6 kb' │ '2.45 x' │
1310
+ │ typebox/custom │ ' 0.6 kb' │ ' 0.2 kb' │ '2.61 x' │
1311
+ │ typebox/format │ ' 0.6 kb' │ ' 0.2 kb' │ '2.66 x' │
1312
+ │ typebox/guard │ ' 23.8 kb' │ ' 11.4 kb' │ '2.08 x' │
1313
+ │ typebox/hash │ ' 4.2 kb' │ ' 1.8 kb' │ '2.30 x' │
1314
+ │ typebox/system │ ' 14.0 kb' │ ' 7.1 kb' │ '1.96 x' │
1315
+ │ typebox/value │ ' 90.0 kb' │ ' 41.8 kb' │ '2.15 x' │
1316
+ │ typebox │ ' 12.0 kb' │ ' 6.4 kb' │ '1.89 x' │
1318
1317
  └──────────────────────┴────────────┴────────────┴─────────────┘
1319
1318
  ```
1320
1319