@sinclair/typebox 0.24.32 → 0.24.35

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
@@ -56,21 +56,34 @@ License MIT
56
56
  - [Overview](#overview)
57
57
  - [Usage](#usage)
58
58
  - [Types](#types)
59
- - [Modifiers](#modifiers)
60
- - [Options](#options)
61
- - [Extended Types](#extended-types)
62
- - [Reference Types](#reference-types)
63
- - [Recursive Types](#recursive-types)
64
- - [Generic Types](#generic-types)
65
- - [Unsafe Types](#unsafe-types)
66
- - [Conditional Types](#conditional-types)
59
+ - [Standard](#types-standard)
60
+ - [Modifiers](#types-modifiers)
61
+ - [Options](#types-options)
62
+ - [Extended](#types-extended)
63
+ - [Reference](#types-reference)
64
+ - [Recursive](#types-recursive)
65
+ - [Generic](#types-generic)
66
+ - [Conditional](#types-conditional)
67
+ - [Unsafe](#types-unsafe)
68
+ - [Guards](#types-guards)
69
+ - [Strict](#types-strict)
67
70
  - [Values](#values)
68
- - [Formats](#formats)
69
- - [Guards](#guards)
70
- - [Strict](#strict)
71
- - [Validation](#validation)
72
- - [Compiler](#compiler)
71
+ - [Create](#values-create)
72
+ - [Clone](#values-clone)
73
+ - [Check](#values-check)
74
+ - [Cast](#values-cast)
75
+ - [Equal](#values-equal)
76
+ - [Diff](#values-diff)
77
+ - [Patch](#values-patch)
78
+ - [Errors](#values-errors)
79
+ - [TypeCheck](#typecheck)
80
+ - [Ajv](#typecheck-ajv)
81
+ - [Compiler](#typecheck-compiler)
82
+ - [Formats](#typecheck-formats)
73
83
  - [Benchmark](#benchmark)
84
+ - [Compile](#benchmark-compile)
85
+ - [Validate](#benchmark-validate)
86
+ - [Compression](#benchmark-compression)
74
87
  - [Contribute](#contribute)
75
88
 
76
89
  <a name="Example"></a>
@@ -148,9 +161,17 @@ function receive(value: T) { // ... as a Type
148
161
  }
149
162
  ```
150
163
 
164
+ <a name='types'></a>
165
+
151
166
  ## Types
152
167
 
153
- The following table outlines the TypeBox mappings between TypeScript and JSON schema.
168
+ 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.
169
+
170
+ <a name='types-standard'></a>
171
+
172
+ ### Standard
173
+
174
+ The following table lists the standard TypeBox types.
154
175
 
155
176
  ```typescript
156
177
  ┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
@@ -342,7 +363,9 @@ The following table outlines the TypeBox mappings between TypeScript and JSON sc
342
363
  └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
343
364
  ```
344
365
 
345
- ## Modifiers
366
+ <a name='types-modifiers'></a>
367
+
368
+ ### Modifiers
346
369
 
347
370
  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.
348
371
 
@@ -384,7 +407,9 @@ TypeBox provides modifiers that can be applied to an objects properties. This al
384
407
  └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
385
408
  ```
386
409
 
387
- ## Options
410
+ <a name='types-options'></a>
411
+
412
+ ### Options
388
413
 
389
414
  You can pass additional JSON schema options on the last argument of any given type. The following are some examples.
390
415
 
@@ -399,7 +424,9 @@ const T = Type.Number({ multipleOf: 2 })
399
424
  const T = Type.Array(Type.Integer(), { minItems: 5 })
400
425
  ```
401
426
 
402
- ## Extended Types
427
+ <a name='types-extended'></a>
428
+
429
+ ### Extended
403
430
 
404
431
  In addition to JSON schema types, TypeBox provides several extended types that allow for `function` and `constructor` types to be composed. These additional types are not valid JSON Schema and will not validate using typical JSON Schema validation. However, these types can be used to frame JSON schema and describe callable interfaces that may receive JSON validated data. These types are as follows.
405
432
 
@@ -461,7 +488,9 @@ In addition to JSON schema types, TypeBox provides several extended types that a
461
488
  └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
462
489
  ```
463
490
 
464
- ## Reference Types
491
+ <a name='types-reference'></a>
492
+
493
+ ### Reference
465
494
 
466
495
  Use `Type.Ref(...)` to create referenced types. The target type must specify an `$id`.
467
496
 
@@ -476,7 +505,9 @@ const R = Type.Ref(T) // const R = {
476
505
  // }
477
506
  ```
478
507
 
479
- ## Recursive Types
508
+ <a name='types-recursive'></a>
509
+
510
+ ### Recursive
480
511
 
481
512
  Use `Type.Recursive(...)` to create recursive types.
482
513
 
@@ -513,7 +544,9 @@ function test(node: Node) {
513
544
  }
514
545
  ```
515
546
 
516
- ## Generic Types
547
+ <a name='types-generic'></a>
548
+
549
+ ### Generic
517
550
 
518
551
  Use functions to create generic types. The following creates a generic `Nullable<T>` type.
519
552
 
@@ -543,59 +576,9 @@ const U = Nullable(Type.Number()) // const U = {
543
576
  type U = Static<typeof U> // type U = number | null
544
577
  ```
545
578
 
546
- ## Unsafe Types
547
-
548
- Use `Type.Unsafe(...)` to create custom schemas with user defined inference rules.
549
-
550
- ```typescript
551
- const T = Type.Unsafe<string>({ type: 'number' }) // const T = {
552
- // type: 'number'
553
- // }
554
-
555
- type T = Static<typeof T> // type T = string
556
- ```
557
-
558
- 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.
579
+ <a name='types-conditional'></a>
559
580
 
560
- ```typescript
561
- import { Type, Static, TSchema } from '@sinclair/typebox'
562
-
563
- //--------------------------------------------------------------------------------------------
564
- //
565
- // Nullable<T>
566
- //
567
- //--------------------------------------------------------------------------------------------
568
-
569
- function Nullable<T extends TSchema>(schema: T) {
570
- return Type.Unsafe<Static<T> | null>({ ...schema, nullable: true })
571
- }
572
-
573
- const T = Nullable(Type.String()) // const T = {
574
- // type: 'string',
575
- // nullable: true
576
- // }
577
-
578
- type T = Static<typeof T> // type T = string | null
579
-
580
-
581
- //--------------------------------------------------------------------------------------------
582
- //
583
- // StringEnum<string[]>
584
- //
585
- //--------------------------------------------------------------------------------------------
586
-
587
- function StringEnum<T extends string[]>(values: [...T]) {
588
- return Type.Unsafe<T[number]>({ type: 'string', enum: values })
589
- }
590
-
591
- const T = StringEnum(['A', 'B', 'C']) // const T = {
592
- // enum: ['A', 'B', 'C']
593
- // }
594
-
595
- type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
596
- ```
597
-
598
- ## Conditional Types
581
+ ### Conditional
599
582
 
600
583
  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.
601
584
 
@@ -646,85 +629,63 @@ The following table shows the TypeBox mappings between TypeScript and JSON schem
646
629
  └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
647
630
  ```
648
631
 
649
- ## Values
632
+ <a name='types-unsafe'></a>
650
633
 
651
- Use the value module to perform common type operations on values. This module provides functionality to create, check and cast values into a given type. Note that this module internally uses dynamic type checking to perform these operations. For faster type checking performance, consider using either Ajv or the TypeBox [TypeCompiler](#compiler).
634
+ ### Unsafe
652
635
 
653
- The value module is provided as an optional import.
636
+ Use `Type.Unsafe(...)` to create custom schemas with user defined inference rules.
654
637
 
655
638
  ```typescript
656
- import { Value } from '@sinclair/typebox/value'
657
- ```
658
- The following demonstrates its use.
659
- ```typescript
660
-
661
-
662
- const T = Type.Object({ x: Type.Number(), y: Type.Number() }, { additionalProperties: false })
663
-
664
- //--------------------------------------------------------------------------------------------
665
- //
666
- // Use Value.Create(T) to create a value from T.
667
- //
668
- //--------------------------------------------------------------------------------------------
639
+ const T = Type.Unsafe<string>({ type: 'number' }) // const T = {
640
+ // type: 'number'
641
+ // }
669
642
 
670
- const V = Value.Create(T) // const V = { x: 0, y: 0 }
643
+ type T = Static<typeof T> // type T = string
644
+ ```
671
645
 
672
- //--------------------------------------------------------------------------------------------
673
- //
674
- // Use Value.Check(T, ...) to check if a value is of type T.
675
- //
676
- //--------------------------------------------------------------------------------------------
646
+ 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.
677
647
 
678
- const R = Value.Check(T, { x: 1 }) // const R = false
648
+ ```typescript
649
+ import { Type, Static, TSchema } from '@sinclair/typebox'
679
650
 
680
651
  //--------------------------------------------------------------------------------------------
681
652
  //
682
- // Use Value.Cast(T, ...) to immutably cast a value into T.
653
+ // Nullable<T>
683
654
  //
684
655
  //--------------------------------------------------------------------------------------------
685
656
 
686
- const A = Value.Cast(T, null) // const A = { x: 0, y: 0 }
687
-
688
- const B = Value.Cast(T, { x: 1 }) // const B = { x: 1, y: 0 }
689
-
690
- const C = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const C = { x: 1, y: 2 }
691
- ```
692
-
693
- ## Formats
694
-
695
- Use the format module to create user defined string formats. This module enables programmatic validation of strings that cannot be easily validated with [pattern](https://json-schema.org/understanding-json-schema/reference/regular_expressions.html) expressions. The format module is used by the Value and TypeCompiler modules only. If using Ajv, please refer to the official Ajv format documentation located [here](https://ajv.js.org/guide/formats.html).
696
-
697
- The format module is an optional import.
698
-
699
- ```typescript
700
- import { Format } from '@sinclair/typebox/format'
701
- ```
657
+ function Nullable<T extends TSchema>(schema: T) {
658
+ return Type.Unsafe<Static<T> | null>({ ...schema, nullable: true })
659
+ }
702
660
 
703
- The following demonstrates its use.
661
+ const T = Nullable(Type.String()) // const T = {
662
+ // type: 'string',
663
+ // nullable: true
664
+ // }
704
665
 
705
- ```typescript
706
- //--------------------------------------------------------------------------------------------
707
- //
708
- // Use Format.Set(format, func) to define custom format
709
- //
710
- //--------------------------------------------------------------------------------------------
666
+ type T = Static<typeof T> // type T = string | null
711
667
 
712
- Format.Set('palindrome', value => value === value.split('').reverse().join(''))
713
668
 
714
669
  //--------------------------------------------------------------------------------------------
715
670
  //
716
- // Use the format property on string types
671
+ // StringEnum<string[]>
717
672
  //
718
673
  //--------------------------------------------------------------------------------------------
719
674
 
720
- const T = Type.String({ format: 'palindrome' })
675
+ function StringEnum<T extends string[]>(values: [...T]) {
676
+ return Type.Unsafe<T[number]>({ type: 'string', enum: values })
677
+ }
721
678
 
722
- Value.Check(T, 'kayak') // true
679
+ const T = StringEnum(['A', 'B', 'C']) // const T = {
680
+ // enum: ['A', 'B', 'C']
681
+ // }
723
682
 
724
- Value.Check(T, 'engine') // false
683
+ type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
725
684
  ```
726
685
 
727
- ## Guards
686
+ <a name='types-guards'></a>
687
+
688
+ ### Guards
728
689
 
729
690
  Use the guard module to test if values are TypeBox types.
730
691
 
@@ -739,7 +700,9 @@ if(TypeGuard.TString(T)) {
739
700
  }
740
701
  ```
741
702
 
742
- ## Strict
703
+ <a name='types-strict'></a>
704
+
705
+ ### Strict
743
706
 
744
707
  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.
745
708
 
@@ -766,21 +729,153 @@ const U = Type.Strict(T) // const U = {
766
729
  // }
767
730
  ```
768
731
 
769
- ## Validation
732
+ <a name='values'></a>
733
+
734
+ ## Values
735
+
736
+ 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.
737
+
738
+ ```typescript
739
+ import { Value } from '@sinclair/typebox/value'
740
+ ```
741
+
742
+ <a name='values-create'></a>
743
+
744
+ ### Create
745
+
746
+ Use the Create function to create a value from a TypeBox type. TypeBox will use default values if specified.
747
+
748
+ ```typescript
749
+ const T = Type.Object({ x: Type.Number(), y: Type.Number({ default: 42 }) })
750
+
751
+ const A = Value.Create(T) // const A = { x: 0, y: 42 }
752
+ ```
753
+
754
+ <a name='values-clone'></a>
755
+
756
+ ### Clone
757
+
758
+ Use the Clone function to deeply clone a value
759
+
760
+ ```typescript
761
+ const A = Value.Clone({ x: 1, y: 2, z: 3 }) // const A = { x: 1, y: 2, z: 3 }
762
+ ```
763
+
764
+ <a name='values-check'></a>
765
+
766
+ ### Check
767
+
768
+ Use the Check function to type check a value
769
+
770
+ ```typescript
771
+ const T = Type.Object({ x: Type.Number() })
772
+
773
+ const R = Value.Check(T, { x: 1 }) // const R = true
774
+ ```
775
+
776
+ <a name='values-cast'></a>
777
+
778
+ ### Cast
779
+
780
+ Use the Cast function to cast a value into a type. The cast function will retain as much information as possible from the original value.
781
+
782
+ ```typescript
783
+ const T = Type.Object({ x: Type.Number(), y: Type.Number() }, { additionalProperties: false })
784
+
785
+ const X = Value.Cast(T, null) // const X = { x: 0, y: 0 }
786
+
787
+ const Y = Value.Cast(T, { x: 1 }) // const Y = { x: 1, y: 0 }
788
+
789
+ const Z = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const Z = { x: 1, y: 2 }
790
+ ```
791
+
792
+ <a name='values-equal'></a>
793
+
794
+ ### Equal
795
+
796
+ Use the Equal function to deeply check for value equality.
797
+
798
+ ```typescript
799
+ const R = Value.Equal( // const R = true
800
+ { x: 1, y: 2, z: 3 },
801
+ { x: 1, y: 2, z: 3 }
802
+ )
803
+ ```
804
+
805
+ <a name='values-diff'></a>
806
+
807
+ ### Diff
808
+
809
+ Use the Diff function to produce a sequence of edits to transform one value into another.
810
+
811
+ ```typescript
812
+ const E = Value.Diff<any>( // const E = [
813
+ { x: 1, y: 2, z: 3 }, // { type: 'update', path: '/y', value: 4 },
814
+ { y: 4, z: 5, w: 6 } // { type: 'update', path: '/z', value: 5 },
815
+ ) // { type: 'insert', path: '/w', value: 6 },
816
+ // { type: 'delete', path: '/x' }
817
+ // ]
818
+ ```
819
+
820
+ <a name='values-patch'></a>
821
+
822
+ ### Patch
823
+
824
+ Use the Patch function to apply edits
825
+
826
+ ```typescript
827
+ const A = { x: 1, y: 2 }
828
+
829
+ const B = { x: 3 }
830
+
831
+ const E = Value.Diff<any>(A, B) // const E = [
832
+ // { type: 'update', path: '/x', value: 3 },
833
+ // { type: 'delete', path: '/y' }
834
+ // ]
835
+
836
+ const C = Value.Patch<any>(A, E) // const C = { x: 3 }
837
+ ```
838
+
839
+
840
+ <a name='values-errors'></a>
841
+
842
+ ### Errors
770
843
 
771
- TypeBox schemas target JSON Schema draft 6 so any validator capable of draft 6 should be fine. A good library to use for validation in JavaScript environments is [Ajv](https://www.npmjs.com/package/ajv). The following example shows setting up Ajv to work with TypeBox.
844
+ Use the Errors function enumerate validation errors.
845
+
846
+ ```typescript
847
+ const T = Type.Object({ x: Type.Number(), y: Type.Number() })
848
+
849
+ const R = [...Value.Errors(T, { x: '42' })] // const R = [{
850
+ // schema: { type: 'number' },
851
+ // path: '/x',
852
+ // value: '42',
853
+ // message: 'Expected number'
854
+ // }, {
855
+ // schema: { type: 'number' },
856
+ // path: '/y',
857
+ // value: undefined,
858
+ // message: 'Expected number'
859
+ // }]
860
+ ```
861
+
862
+ <a name='typecheck'></a>
863
+
864
+ ## TypeCheck
865
+
866
+ TypeBox is written to target JSON Schema Draft 6 and can be used with any Draft 6 compliant validator. TypeBox is developed and tested against Ajv and can be used in any application already making use of this validator. Additionally, TypeBox also provides an optional type compiler that can be used to attain improved compilation and validation performance for certain application types.
867
+
868
+ <a name='typecheck-ajv'></a>
869
+
870
+ ### Ajv
871
+
872
+ The following example shows setting up Ajv to work with TypeBox.
772
873
 
773
874
  ```bash
774
875
  $ npm install ajv ajv-formats --save
775
876
  ```
776
877
 
777
878
  ```typescript
778
- //--------------------------------------------------------------------------------------------
779
- //
780
- // Import TypeBox and Ajv
781
- //
782
- //--------------------------------------------------------------------------------------------
783
-
784
879
  import { Type } from '@sinclair/typebox'
785
880
  import addFormats from 'ajv-formats'
786
881
  import Ajv from 'ajv'
@@ -829,9 +924,9 @@ const T = Type.Object({
829
924
  const R = ajv.validate(T, { x: 1, y: 2, z: 3 }) // const R = true
830
925
  ```
831
926
 
832
- Please refer to the official Ajv [documentation](https://ajv.js.org/guide/getting-started.html) for additional information on using Ajv.
927
+ <a name='typecheck-compiler'></a>
833
928
 
834
- ## Compiler
929
+ ### Compiler
835
930
 
836
931
  TypeBox provides an optional 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. If defining custom types with `Type.Unsafe<T>` please consider Ajv.
837
932
 
@@ -894,12 +989,44 @@ console.log(C.Code()) // return function check(va
894
989
  // }
895
990
  ```
896
991
 
992
+ <a name='typecheck-formats'></a>
993
+
994
+ ### Formats
995
+
996
+ Use the format module to create user defined string formats. The format module is used by the Value and TypeCompiler modules only. If using Ajv, please refer to the official Ajv format documentation located [here](https://ajv.js.org/guide/formats.html).
997
+
998
+ The format module is an optional import.
999
+
1000
+ ```typescript
1001
+ import { Format } from '@sinclair/typebox/format'
1002
+ ```
1003
+
1004
+ The following creates a `palindrome` string format.
1005
+
1006
+ ```typescript
1007
+ Format.Set('palindrome', value => value === value.split('').reverse().join(''))
1008
+ ```
1009
+
1010
+ Once set, this format can then be used by the TypeCompiler and Value modules.
1011
+
1012
+ ```typescript
1013
+ const T = Type.String({ format: 'palindrome' })
1014
+
1015
+ const A = TypeCompiler.Compile(T).Check('engine') // const A = false
1016
+
1017
+ const B = Value.Check(T, 'kayak') // const B = true
1018
+ ```
1019
+
1020
+ <a name='benchmark'></a>
1021
+
897
1022
  ## Benchmark
898
1023
 
899
1024
  This project maintains a set of benchmarks that measure Ajv, Value and TypeCompiler compilation and validation performance. These benchmarks can be run locally by cloning this repository and running `npm run benchmark`. The results below show for Ajv version 8.11.0.
900
1025
 
901
1026
  For additional comparative benchmarks, please refer to [typescript-runtime-type-benchmarks](https://moltar.github.io/typescript-runtime-type-benchmarks/).
902
1027
 
1028
+ <a name='benchmark-compile'></a>
1029
+
903
1030
  ### Compile
904
1031
 
905
1032
  This benchmark measures compilation performance for varying types. You can review this benchmark [here](https://github.com/sinclairzx81/typebox/blob/master/benchmark/measurement/module/compile.ts).
@@ -908,32 +1035,34 @@ This benchmark measures compilation performance for varying types. You can revie
908
1035
  ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┐
909
1036
  │ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │
910
1037
  ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┤
911
- │ Number │ 2000 │ ' 402 ms' │ ' 8 ms' │ ' 50.25 x' │
912
- │ String │ 2000 │ ' 316 ms' │ ' 8 ms' │ ' 39.50 x' │
913
- │ Boolean │ 2000 │ ' 308 ms' │ ' 6 ms' │ ' 51.33 x' │
914
- │ Null │ 2000 │ ' 259 ms' │ ' 5 ms' │ ' 51.80 x' │
915
- │ RegEx │ 2000 │ ' 479 ms' │ ' 11 ms' │ ' 43.55 x' │
916
- │ ObjectA │ 2000 │ ' 2766 ms' │ ' 41 ms' │ ' 67.46 x' │
917
- │ ObjectB │ 2000 │ ' 3062 ms' │ ' 29 ms' │ ' 105.59 x' │
918
- │ Tuple │ 2000 │ ' 1258 ms' │ ' 21 ms' │ ' 59.90 x' │
919
- │ Union │ 2000 │ ' 1449 ms' │ ' 29 ms' │ ' 49.97 x' │
920
- │ Vector4 │ 2000 │ ' 1616 ms' │ ' 16 ms' │ ' 101.00 x' │
921
- │ Matrix4 │ 2000 │ ' 975 ms' │ ' 8 ms' │ ' 121.88 x' │
922
- │ Literal_String │ 2000 │ ' 350 ms' │ ' 6 ms' │ ' 58.33 x' │
923
- │ Literal_Number │ 2000 │ ' 386 ms' │ ' 5 ms' │ ' 77.20 x' │
924
- │ Literal_Boolean │ 2000 │ ' 377 ms' │ ' 4 ms' │ ' 94.25 x' │
925
- │ Array_Number │ 2000 │ ' 737 ms' │ ' 7 ms' │ ' 105.29 x' │
926
- │ Array_String │ 2000 │ ' 765 ms' │ ' 7 ms' │ ' 109.29 x' │
927
- │ Array_Boolean │ 2000 │ ' 783 ms' │ ' 8 ms' │ ' 97.88 x' │
928
- │ Array_ObjectA │ 2000 │ ' 3578 ms' │ ' 31 ms' │ ' 115.42 x' │
929
- │ Array_ObjectB │ 2000 │ ' 3718 ms' │ ' 33 ms' │ ' 112.67 x' │
930
- │ Array_Tuple │ 2000 │ ' 2259 ms' │ ' 14 ms' │ ' 161.36 x' │
931
- │ Array_Union │ 2000 │ ' 1704 ms' │ ' 20 ms' │ ' 85.20 x' │
932
- │ Array_Vector4 │ 2000 │ ' 2293 ms' │ ' 17 ms' │ ' 134.88 x' │
933
- │ Array_Matrix4 │ 2000 │ ' 1575 ms' │ ' 12 ms' │ ' 131.25 x' │
1038
+ │ Number │ 2000 │ ' 410 ms' │ ' 10 ms' │ ' 41.00 x' │
1039
+ │ String │ 2000 │ ' 321 ms' │ ' 8 ms' │ ' 40.13 x' │
1040
+ │ Boolean │ 2000 │ ' 314 ms' │ ' 6 ms' │ ' 52.33 x' │
1041
+ │ Null │ 2000 │ ' 273 ms' │ ' 6 ms' │ ' 45.50 x' │
1042
+ │ RegEx │ 2000 │ ' 485 ms' │ ' 11 ms' │ ' 44.09 x' │
1043
+ │ ObjectA │ 2000 │ ' 2867 ms' │ ' 41 ms' │ ' 69.93 x' │
1044
+ │ ObjectB │ 2000 │ ' 3018 ms' │ ' 30 ms' │ ' 100.60 x' │
1045
+ │ Tuple │ 2000 │ ' 1298 ms' │ ' 21 ms' │ ' 61.81 x' │
1046
+ │ Union │ 2000 │ ' 1340 ms' │ ' 23 ms' │ ' 58.26 x' │
1047
+ │ Vector4 │ 2000 │ ' 1794 ms' │ ' 22 ms' │ ' 81.55 x' │
1048
+ │ Matrix4 │ 2000 │ ' 1037 ms' │ ' 12 ms' │ ' 86.42 x' │
1049
+ │ Literal_String │ 2000 │ ' 380 ms' │ ' 9 ms' │ ' 42.22 x' │
1050
+ │ Literal_Number │ 2000 │ ' 446 ms' │ ' 8 ms' │ ' 55.75 x' │
1051
+ │ Literal_Boolean │ 2000 │ ' 400 ms' │ ' 4 ms' │ ' 100.00 x' │
1052
+ │ Array_Number │ 2000 │ ' 764 ms' │ ' 6 ms' │ ' 127.33 x' │
1053
+ │ Array_String │ 2000 │ ' 785 ms' │ ' 9 ms' │ ' 87.22 x' │
1054
+ │ Array_Boolean │ 2000 │ ' 796 ms' │ ' 6 ms' │ ' 132.67 x' │
1055
+ │ Array_ObjectA │ 2000 │ ' 3678 ms' │ ' 34 ms' │ ' 108.18 x' │
1056
+ │ Array_ObjectB │ 2000 │ ' 3875 ms' │ ' 34 ms' │ ' 113.97 x' │
1057
+ │ Array_Tuple │ 2000 │ ' 2231 ms' │ ' 15 ms' │ ' 148.73 x' │
1058
+ │ Array_Union │ 2000 │ ' 1713 ms' │ ' 18 ms' │ ' 95.17 x' │
1059
+ │ Array_Vector4 │ 2000 │ ' 2381 ms' │ ' 16 ms' │ ' 148.81 x' │
1060
+ │ Array_Matrix4 │ 2000 │ ' 1644 ms' │ ' 14 ms' │ ' 117.43 x' │
934
1061
  └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┘
935
1062
  ```
936
1063
 
1064
+ <a name='benchmark-validate'></a>
1065
+
937
1066
  ### Validate
938
1067
 
939
1068
  This benchmark measures validation performance for varying types. You can review this benchmark [here](https://github.com/sinclairzx81/typebox/blob/master/benchmark/measurement/module/check.ts).
@@ -942,34 +1071,36 @@ This benchmark measures validation performance for varying types. You can review
942
1071
  ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
943
1072
  │ (index) │ Iterations │ ValueCheck │ Ajv │ TypeCompiler │ Performance │
944
1073
  ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┼──────────────┤
945
- │ Number │ 1000000 │ ' 38 ms' │ ' 6 ms' │ ' 5 ms' │ ' 1.20 x' │
946
- │ String │ 1000000 │ ' 26 ms' │ ' 23 ms' │ ' 12 ms' │ ' 1.92 x' │
947
- │ Boolean │ 1000000 │ ' 26 ms' │ ' 23 ms' │ ' 11 ms' │ ' 2.09 x' │
948
- │ Null │ 1000000 │ ' 29 ms' │ ' 24 ms' │ ' 12 ms' │ ' 2.00 x' │
949
- │ RegEx │ 1000000 │ ' 169 ms' │ ' 47 ms' │ ' 37 ms' │ ' 1.27 x' │
950
- │ ObjectA │ 1000000 │ ' 551 ms' │ ' 45 ms' │ ' 23 ms' │ ' 1.96 x' │
951
- │ ObjectB │ 1000000 │ ' 995 ms' │ ' 49 ms' │ ' 39 ms' │ ' 1.26 x' │
952
- │ Tuple │ 1000000 │ ' 115 ms' │ ' 30 ms' │ ' 14 ms' │ ' 2.14 x' │
953
- │ Union │ 1000000 │ ' 294 ms' │ ' 30 ms' │ ' 14 ms' │ ' 2.14 x' │
954
- │ Recursive │ 1000000 │ ' 3308 ms' │ ' 429 ms' │ ' 174 ms' │ ' 2.47 x' │
955
- │ Vector4 │ 1000000 │ ' 145 ms' │ ' 25 ms' │ ' 13 ms' │ ' 1.92 x' │
956
- │ Matrix4 │ 1000000 │ ' 663 ms' │ ' 42 ms' │ ' 34 ms' │ ' 1.24 x' │
957
- │ Literal_String │ 1000000 │ ' 46 ms' │ ' 21 ms' │ ' 11 ms' │ ' 1.91 x' │
958
- │ Literal_Number │ 1000000 │ ' 50 ms' │ ' 26 ms' │ ' 11 ms' │ ' 2.36 x' │
959
- │ Literal_Boolean │ 1000000 │ ' 45 ms' │ ' 24 ms' │ ' 11 ms' │ ' 2.18 x' │
960
- │ Array_Number │ 1000000 │ ' 411 ms' │ ' 35 ms' │ ' 19 ms' │ ' 1.84 x' │
961
- │ Array_String │ 1000000 │ ' 438 ms' │ ' 33 ms' │ ' 20 ms' │ ' 1.65 x' │
962
- │ Array_Boolean │ 1000000 │ ' 444 ms' │ ' 38 ms' │ ' 24 ms' │ ' 1.58 x' │
963
- │ Array_ObjectA │ 1000000 │ ' 13714 ms' │ ' 2819 ms' │ ' 1791 ms' │ ' 1.57 x' │
964
- │ Array_ObjectB │ 1000000 │ ' 15855 ms' │ ' 2965 ms' │ ' 2066 ms' │ ' 1.44 x' │
965
- │ Array_Tuple │ 1000000 │ ' 1682 ms' │ ' 94 ms' │ ' 71 ms' │ ' 1.32 x' │
966
- │ Array_Union │ 1000000 │ ' 4575 ms' │ ' 239 ms' │ ' 86 ms' │ ' 2.78 x' │
967
- │ Array_Recursive │ 1000000 │ ' 51970 ms' │ ' 7192 ms' │ ' 2617 ms' │ ' 2.75 x' │
968
- │ Array_Vector4 │ 1000000 │ ' 2097 ms' │ ' 100 ms' │ ' 54 ms' │ ' 1.85 x' │
969
- │ Array_Matrix4 │ 1000000 │ ' 11596 ms' │ ' 381 ms' │ ' 327 ms' │ ' 1.17 x' │
1074
+ │ Number │ 1000000 │ ' 29 ms' │ ' 6 ms' │ ' 5 ms' │ ' 1.20 x' │
1075
+ │ String │ 1000000 │ ' 24 ms' │ ' 23 ms' │ ' 11 ms' │ ' 2.09 x' │
1076
+ │ Boolean │ 1000000 │ ' 21 ms' │ ' 22 ms' │ ' 10 ms' │ ' 2.20 x' │
1077
+ │ Null │ 1000000 │ ' 29 ms' │ ' 26 ms' │ ' 15 ms' │ ' 1.73 x' │
1078
+ │ RegEx │ 1000000 │ ' 180 ms' │ ' 46 ms' │ ' 36 ms' │ ' 1.28 x' │
1079
+ │ ObjectA │ 1000000 │ ' 548 ms' │ ' 36 ms' │ ' 24 ms' │ ' 1.50 x' │
1080
+ │ ObjectB │ 1000000 │ ' 995 ms' │ ' 52 ms' │ ' 40 ms' │ ' 1.30 x' │
1081
+ │ Tuple │ 1000000 │ ' 119 ms' │ ' 23 ms' │ ' 14 ms' │ ' 1.64 x' │
1082
+ │ Union │ 1000000 │ ' 308 ms' │ ' 25 ms' │ ' 15 ms' │ ' 1.67 x' │
1083
+ │ Recursive │ 1000000 │ ' 3405 ms' │ ' 458 ms' │ ' 214 ms' │ ' 2.14 x' │
1084
+ │ Vector4 │ 1000000 │ ' 144 ms' │ ' 23 ms' │ ' 12 ms' │ ' 1.92 x' │
1085
+ │ Matrix4 │ 1000000 │ ' 608 ms' │ ' 42 ms' │ ' 29 ms' │ ' 1.45 x' │
1086
+ │ Literal_String │ 1000000 │ ' 46 ms' │ ' 21 ms' │ ' 10 ms' │ ' 2.10 x' │
1087
+ │ Literal_Number │ 1000000 │ ' 48 ms' │ ' 20 ms' │ ' 9 ms' │ ' 2.22 x' │
1088
+ │ Literal_Boolean │ 1000000 │ ' 50 ms' │ ' 20 ms' │ ' 10 ms' │ ' 2.00 x' │
1089
+ │ Array_Number │ 1000000 │ ' 467 ms' │ ' 34 ms' │ ' 19 ms' │ ' 1.79 x' │
1090
+ │ Array_String │ 1000000 │ ' 488 ms' │ ' 32 ms' │ ' 20 ms' │ ' 1.60 x' │
1091
+ │ Array_Boolean │ 1000000 │ ' 476 ms' │ ' 34 ms' │ ' 24 ms' │ ' 1.42 x' │
1092
+ │ Array_ObjectA │ 1000000 │ ' 14220 ms' │ ' 2819 ms' │ ' 1810 ms' │ ' 1.56 x' │
1093
+ │ Array_ObjectB │ 1000000 │ ' 16344 ms' │ ' 3067 ms' │ ' 2147 ms' │ ' 1.43 x' │
1094
+ │ Array_Tuple │ 1000000 │ ' 1702 ms' │ ' 92 ms' │ ' 71 ms' │ ' 1.30 x' │
1095
+ │ Array_Union │ 1000000 │ ' 4754 ms' │ ' 249 ms' │ ' 89 ms' │ ' 2.80 x' │
1096
+ │ Array_Recursive │ 1000000 │ ' 56465 ms' │ ' 6921 ms' │ ' 2411 ms' │ ' 2.87 x' │
1097
+ │ Array_Vector4 │ 1000000 │ ' 1974 ms' │ ' 109 ms' │ ' 55 ms' │ ' 1.98 x' │
1098
+ │ Array_Matrix4 │ 1000000 │ ' 10722 ms' │ ' 400 ms' │ ' 320 ms' │ ' 1.25 x' │
970
1099
  └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
971
1100
  ```
972
1101
 
1102
+ <a name='benchmark-compression'></a>
1103
+
973
1104
  ### Compression
974
1105
 
975
1106
  The following table lists esbuild compiled and minified sizes for each TypeBox module.
@@ -980,13 +1111,15 @@ The following table lists esbuild compiled and minified sizes for each TypeBox m
980
1111
  ├──────────────────────┼────────────┼────────────┼─────────────┤
981
1112
  │ typebox/compiler │ ' 48 kb' │ ' 24 kb' │ '2.00 x' │
982
1113
  │ typebox/conditional │ ' 41 kb' │ ' 16 kb' │ '2.47 x' │
983
- │ typebox/format │ ' 0 kb' │ ' 0 kb' │ '2.68 x' │
1114
+ │ typebox/format │ ' 0 kb' │ ' 0 kb' │ '2.66 x' │
984
1115
  │ typebox/guard │ ' 20 kb' │ ' 9 kb' │ '2.08 x' │
985
- │ typebox/value │ ' 55 kb' │ ' 25 kb' │ '2.15 x' │
1116
+ │ typebox/value │ ' 68 kb' │ ' 31 kb' │ '2.15 x' │
986
1117
  │ typebox │ ' 11 kb' │ ' 5 kb' │ '1.91 x' │
987
1118
  └──────────────────────┴────────────┴────────────┴─────────────┘
988
1119
  ```
989
1120
 
1121
+ <a name='contribute'></a>
1122
+
990
1123
  ## Contribute
991
1124
 
992
1125
  TypeBox is open to community contribution. Please ensure you submit an open issue before submitting your pull request. The TypeBox project preferences open community discussion prior to accepting new features.