@sinclair/typebox 0.24.25 → 0.24.28

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/guard/guard.js CHANGED
@@ -27,8 +27,15 @@ THE SOFTWARE.
27
27
 
28
28
  ---------------------------------------------------------------------------*/
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.TypeGuard = void 0;
30
+ exports.TypeGuard = exports.TypeGuardInvalidTypeError = void 0;
31
31
  const Types = require("../typebox");
32
+ class TypeGuardInvalidTypeError extends Error {
33
+ constructor(schema) {
34
+ super('TypeGuard: Invalid type');
35
+ this.schema = schema;
36
+ }
37
+ }
38
+ exports.TypeGuardInvalidTypeError = TypeGuardInvalidTypeError;
32
39
  /** TypeGuard tests that values conform to a known TypeBox type specification */
33
40
  var TypeGuard;
34
41
  (function (TypeGuard) {
@@ -47,6 +54,17 @@ var TypeGuard;
47
54
  return false;
48
55
  }
49
56
  }
57
+ function IsValidPropertyKey(value) {
58
+ if (typeof value !== 'string')
59
+ return false;
60
+ for (let i = 0; i < value.length; i++) {
61
+ const code = value.charCodeAt(i);
62
+ if ((code >= 7 && code <= 13) || code === 27 || code === 127) {
63
+ return false;
64
+ }
65
+ }
66
+ return true;
67
+ }
50
68
  function IsString(value) {
51
69
  return typeof value === 'string';
52
70
  }
@@ -66,26 +84,33 @@ var TypeGuard;
66
84
  return value === undefined || (value !== undefined && IsString(value));
67
85
  }
68
86
  function IsOptionalPattern(value) {
69
- return value === undefined || (value !== undefined && IsPattern(value));
87
+ return value === undefined || (value !== undefined && IsString(value) && IsPattern(value));
70
88
  }
71
89
  /** Returns true if the given schema is TAny */
72
90
  function TAny(schema) {
73
- return IsObject(schema) && schema[Types.Kind] === 'Any';
91
+ return IsObject(schema) && schema[Types.Kind] === 'Any' && IsOptionalString(schema.$id);
74
92
  }
75
93
  TypeGuard.TAny = TAny;
76
94
  /** Returns true if the given schema is TArray */
77
95
  function TArray(schema) {
78
- return IsObject(schema) && schema[Types.Kind] === 'Array' && schema.type === 'array' && TSchema(schema.items) && IsOptionalNumber(schema.minItems) && IsOptionalNumber(schema.maxItems);
96
+ return (IsObject(schema) &&
97
+ schema[Types.Kind] === 'Array' &&
98
+ schema.type === 'array' &&
99
+ IsOptionalString(schema.$id) &&
100
+ TSchema(schema.items) &&
101
+ IsOptionalNumber(schema.minItems) &&
102
+ IsOptionalNumber(schema.maxItems) &&
103
+ IsOptionalBoolean(schema.uniqueItems));
79
104
  }
80
105
  TypeGuard.TArray = TArray;
81
106
  /** Returns true if the given schema is TBoolean */
82
107
  function TBoolean(schema) {
83
- return IsObject(schema) && schema[Types.Kind] === 'Boolean' && schema.type === 'boolean';
108
+ return IsObject(schema) && schema[Types.Kind] === 'Boolean' && schema.type === 'boolean' && IsOptionalString(schema.$id);
84
109
  }
85
110
  TypeGuard.TBoolean = TBoolean;
86
111
  /** Returns true if the given schema is TConstructor */
87
112
  function TConstructor(schema) {
88
- if (!(IsObject(schema) && schema[Types.Kind] === 'Constructor' && schema.type === 'constructor' && IsArray(schema.parameters) && TSchema(schema.returns))) {
113
+ if (!(IsObject(schema) && schema[Types.Kind] === 'Constructor' && schema.type === 'constructor' && IsOptionalString(schema.$id) && IsArray(schema.parameters) && TSchema(schema.returns))) {
89
114
  return false;
90
115
  }
91
116
  for (const parameter of schema.parameters) {
@@ -97,7 +122,7 @@ var TypeGuard;
97
122
  TypeGuard.TConstructor = TConstructor;
98
123
  /** Returns true if the given schema is TFunction */
99
124
  function TFunction(schema) {
100
- if (!(IsObject(schema) && schema[Types.Kind] === 'Function' && schema.type === 'function' && IsArray(schema.parameters) && TSchema(schema.returns))) {
125
+ if (!(IsObject(schema) && schema[Types.Kind] === 'Function' && schema.type === 'function' && IsOptionalString(schema.$id) && IsArray(schema.parameters) && TSchema(schema.returns))) {
101
126
  return false;
102
127
  }
103
128
  for (const parameter of schema.parameters) {
@@ -112,6 +137,7 @@ var TypeGuard;
112
137
  return (IsObject(schema) &&
113
138
  schema[Types.Kind] === 'Integer' &&
114
139
  schema.type === 'integer' &&
140
+ IsOptionalString(schema.$id) &&
115
141
  IsOptionalNumber(schema.multipleOf) &&
116
142
  IsOptionalNumber(schema.minimum) &&
117
143
  IsOptionalNumber(schema.maximum) &&
@@ -121,12 +147,12 @@ var TypeGuard;
121
147
  TypeGuard.TInteger = TInteger;
122
148
  /** Returns true if the given schema is TLiteral */
123
149
  function TLiteral(schema) {
124
- return IsObject(schema) && schema[Types.Kind] === 'Literal' && (IsString(schema.const) || IsNumber(schema.const) || IsBoolean(schema.const));
150
+ return IsObject(schema) && schema[Types.Kind] === 'Literal' && IsOptionalString(schema.$id) && (IsString(schema.const) || IsNumber(schema.const) || IsBoolean(schema.const));
125
151
  }
126
152
  TypeGuard.TLiteral = TLiteral;
127
153
  /** Returns true if the given schema is TNull */
128
154
  function TNull(schema) {
129
- return IsObject(schema) && schema[Types.Kind] === 'Null' && schema.type === 'null';
155
+ return IsObject(schema) && schema[Types.Kind] === 'Null' && schema.type === 'null' && IsOptionalString(schema.$id);
130
156
  }
131
157
  TypeGuard.TNull = TNull;
132
158
  /** Returns true if the given schema is TNumber */
@@ -134,6 +160,7 @@ var TypeGuard;
134
160
  return (IsObject(schema) &&
135
161
  schema[Types.Kind] === 'Number' &&
136
162
  schema.type === 'number' &&
163
+ IsOptionalString(schema.$id) &&
137
164
  IsOptionalNumber(schema.multipleOf) &&
138
165
  IsOptionalNumber(schema.minimum) &&
139
166
  IsOptionalNumber(schema.maximum) &&
@@ -146,14 +173,17 @@ var TypeGuard;
146
173
  if (!(IsObject(schema) &&
147
174
  schema[Types.Kind] === 'Object' &&
148
175
  schema.type === 'object' &&
176
+ IsOptionalString(schema.$id) &&
149
177
  IsObject(schema.properties) &&
150
178
  IsOptionalBoolean(schema.additionalProperties) &&
151
179
  IsOptionalNumber(schema.minProperties) &&
152
180
  IsOptionalNumber(schema.maxProperties))) {
153
181
  return false;
154
182
  }
155
- for (const property of Object.values(schema.properties)) {
156
- if (!TSchema(property))
183
+ for (const [key, value] of Object.entries(schema.properties)) {
184
+ if (!IsValidPropertyKey(key))
185
+ return false;
186
+ if (!TSchema(value))
157
187
  return false;
158
188
  }
159
189
  return true;
@@ -161,12 +191,12 @@ var TypeGuard;
161
191
  TypeGuard.TObject = TObject;
162
192
  /** Returns true if the given schema is TPromise */
163
193
  function TPromise(schema) {
164
- return IsObject(schema) && schema[Types.Kind] === 'Promise' && schema.type === 'promise' && TSchema(schema.item);
194
+ return IsObject(schema) && schema[Types.Kind] === 'Promise' && schema.type === 'promise' && IsOptionalString(schema.$id) && TSchema(schema.item);
165
195
  }
166
196
  TypeGuard.TPromise = TPromise;
167
197
  /** Returns true if the given schema is TRecord */
168
198
  function TRecord(schema) {
169
- if (!(IsObject(schema) && schema[Types.Kind] === 'Record' && schema.type === 'object' && IsObject(schema.patternProperties))) {
199
+ if (!(IsObject(schema) && schema[Types.Kind] === 'Record' && schema.type === 'object' && IsOptionalString(schema.$id) && schema.additionalProperties === false && IsObject(schema.patternProperties))) {
170
200
  return false;
171
201
  }
172
202
  const keys = Object.keys(schema.patternProperties);
@@ -184,22 +214,29 @@ var TypeGuard;
184
214
  TypeGuard.TRecord = TRecord;
185
215
  /** Returns true if the given schema is TSelf */
186
216
  function TSelf(schema) {
187
- return IsObject(schema) && schema[Types.Kind] === 'Self' && IsString(schema.$ref);
217
+ return IsObject(schema) && schema[Types.Kind] === 'Self' && IsOptionalString(schema.$id) && IsString(schema.$ref);
188
218
  }
189
219
  TypeGuard.TSelf = TSelf;
190
220
  /** Returns true if the given schema is TRef */
191
221
  function TRef(schema) {
192
- return IsObject(schema) && schema[Types.Kind] === 'Ref' && IsString(schema.$ref);
222
+ return IsObject(schema) && schema[Types.Kind] === 'Ref' && IsOptionalString(schema.$id) && IsString(schema.$ref);
193
223
  }
194
224
  TypeGuard.TRef = TRef;
195
225
  /** Returns true if the given schema is TString */
196
226
  function TString(schema) {
197
- return IsObject(schema) && schema[Types.Kind] === 'String' && schema.type === 'string' && IsOptionalNumber(schema.minLength) && IsOptionalNumber(schema.maxLength) && IsOptionalPattern(schema.pattern) && IsOptionalString(schema.format);
227
+ return (IsObject(schema) &&
228
+ schema[Types.Kind] === 'String' &&
229
+ schema.type === 'string' &&
230
+ IsOptionalString(schema.$id) &&
231
+ IsOptionalNumber(schema.minLength) &&
232
+ IsOptionalNumber(schema.maxLength) &&
233
+ IsOptionalPattern(schema.pattern) &&
234
+ IsOptionalString(schema.format));
198
235
  }
199
236
  TypeGuard.TString = TString;
200
237
  /** Returns true if the given schema is TTuple */
201
238
  function TTuple(schema) {
202
- if (!(IsObject(schema) && schema[Types.Kind] === 'Tuple' && schema.type === 'array' && IsNumber(schema.minItems) && IsNumber(schema.maxItems) && schema.minItems === schema.maxItems)) {
239
+ if (!(IsObject(schema) && schema[Types.Kind] === 'Tuple' && schema.type === 'array' && IsOptionalString(schema.$id) && IsNumber(schema.minItems) && IsNumber(schema.maxItems) && schema.minItems === schema.maxItems)) {
203
240
  return false;
204
241
  }
205
242
  if (schema.items === undefined && schema.additionalItems === undefined && schema.minItems === 0) {
@@ -217,12 +254,12 @@ var TypeGuard;
217
254
  TypeGuard.TTuple = TTuple;
218
255
  /** Returns true if the given schema is TUndefined */
219
256
  function TUndefined(schema) {
220
- return IsObject(schema) && schema[Types.Kind] === 'Undefined' && schema.type === 'object' && schema.specialized === 'Undefined';
257
+ return IsObject(schema) && schema[Types.Kind] === 'Undefined' && schema.type === 'object' && IsOptionalString(schema.$id) && schema.specialized === 'Undefined';
221
258
  }
222
259
  TypeGuard.TUndefined = TUndefined;
223
260
  /** Returns true if the given schema is TUnion */
224
261
  function TUnion(schema) {
225
- if (!(IsObject(schema) && schema[Types.Kind] === 'Union' && IsArray(schema.anyOf))) {
262
+ if (!(IsObject(schema) && schema[Types.Kind] === 'Union' && IsArray(schema.anyOf) && IsOptionalString(schema.$id))) {
226
263
  return false;
227
264
  }
228
265
  for (const inner of schema.anyOf) {
@@ -234,17 +271,23 @@ var TypeGuard;
234
271
  TypeGuard.TUnion = TUnion;
235
272
  /** Returns true if the given schema is TUint8Array */
236
273
  function TUint8Array(schema) {
237
- return IsObject(schema) && schema[Types.Kind] === 'Uint8Array' && schema.type === 'object' && schema.specialized === 'Uint8Array' && IsOptionalNumber(schema.minByteLength) && IsOptionalNumber(schema.maxByteLength);
274
+ return (IsObject(schema) &&
275
+ schema[Types.Kind] === 'Uint8Array' &&
276
+ schema.type === 'object' &&
277
+ IsOptionalString(schema.$id) &&
278
+ schema.specialized === 'Uint8Array' &&
279
+ IsOptionalNumber(schema.minByteLength) &&
280
+ IsOptionalNumber(schema.maxByteLength));
238
281
  }
239
282
  TypeGuard.TUint8Array = TUint8Array;
240
283
  /** Returns true if the given schema is TUnknown */
241
284
  function TUnknown(schema) {
242
- return IsObject(schema) && schema[Types.Kind] === 'Unknown';
285
+ return IsObject(schema) && schema[Types.Kind] === 'Unknown' && IsOptionalString(schema.$id);
243
286
  }
244
287
  TypeGuard.TUnknown = TUnknown;
245
288
  /** Returns true if the given schema is TVoid */
246
289
  function TVoid(schema) {
247
- return IsObject(schema) && schema[Types.Kind] === 'Void' && schema.type === 'null';
290
+ return IsObject(schema) && schema[Types.Kind] === 'Void' && schema.type === 'null' && IsOptionalString(schema.$id);
248
291
  }
249
292
  TypeGuard.TVoid = TVoid;
250
293
  /** Returns true if the given schema is TSchema */
@@ -272,4 +315,14 @@ var TypeGuard;
272
315
  TVoid(schema));
273
316
  }
274
317
  TypeGuard.TSchema = TSchema;
318
+ /** Asserts if this schema and associated references are valid. */
319
+ function Assert(schema, references = []) {
320
+ if (!TSchema(schema))
321
+ throw new TypeGuardInvalidTypeError(schema);
322
+ for (const schema of references) {
323
+ if (!TSchema(schema))
324
+ throw new TypeGuardInvalidTypeError(schema);
325
+ }
326
+ }
327
+ TypeGuard.Assert = Assert;
275
328
  })(TypeGuard = exports.TypeGuard || (exports.TypeGuard = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.24.25",
3
+ "version": "0.24.28",
4
4
  "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
@@ -26,7 +26,7 @@
26
26
  "publish": "hammer task publish"
27
27
  },
28
28
  "devDependencies": {
29
- "@sinclair/hammer": "^0.16.3",
29
+ "@sinclair/hammer": "^0.17.0",
30
30
  "@types/chai": "^4.3.0",
31
31
  "@types/mocha": "^9.1.0",
32
32
  "@types/node": "^17.0.12",
package/readme.md CHANGED
@@ -19,16 +19,16 @@
19
19
 
20
20
  ## Install
21
21
 
22
- #### Node
22
+ Node
23
23
 
24
24
  ```bash
25
25
  $ npm install @sinclair/typebox --save
26
26
  ```
27
27
 
28
- #### Deno
28
+ Deno and ESM
29
29
 
30
30
  ```typescript
31
- import { Static, Type } from 'https://deno.land/x/typebox/src/typebox.ts'
31
+ import { Static, Type } from 'https://esm.sh/@sinclair/typebox'
32
32
  ```
33
33
 
34
34
  ## Example
@@ -45,9 +45,9 @@ type T = Static<typeof T> // type T = string
45
45
 
46
46
  ## Overview
47
47
 
48
- TypeBox is a type builder library that creates in-memory JSON Schema objects that can be statically inferred as TypeScript types. The schemas produced by this library are designed to match the static type checking rules of the TypeScript compiler. TypeBox enables one to create unified types that can be statically checked by TypeScript and runtime asserted using standard JSON Schema validation.
48
+ 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.
49
49
 
50
- TypeBox can be used as a simple tool to build up complex schemas or integrated into RPC or REST services to help validate JSON data received over the wire.
50
+ 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.
51
51
 
52
52
  License MIT
53
53
 
@@ -194,7 +194,7 @@ The following table outlines the TypeBox mappings between TypeScript and JSON sc
194
194
  │ │ │ │
195
195
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
196
196
  │ const T = Type.Literal(42) │ type T = 42 │ const T = { │
197
- │ │ │ const: 42
197
+ │ │ │ const: 42,
198
198
  │ │ │ type: 'number' │
199
199
  │ │ │ } │
200
200
  │ │ │ │
@@ -506,9 +506,8 @@ type Node = Static<typeof Node> // type Node = {
506
506
  // }
507
507
 
508
508
  function test(node: Node) {
509
- const id = node.nodes[0].nodes[0].nodes[0] // id is string
510
- .nodes[0].nodes[0].nodes[0]
511
- .nodes[0].nodes[0].nodes[0]
509
+ const id = node.nodes[0].nodes[0] // id is string
510
+ .nodes[0].nodes[0]
512
511
  .id
513
512
  }
514
513
  ```
@@ -555,7 +554,7 @@ const T = Type.Unsafe<string>({ type: 'number' }) // const T = {
555
554
  type T = Static<typeof T> // type T = string
556
555
  ```
557
556
 
558
- The `Type.Unsafe(...)` function can be used to create schemas for validators that require specific schema representations. An example of this would be OpenAPI's `nullable` and `enum` schemas which are not provided by TypeBox. The following demonstrates using `Type.Unsafe(...)` to create these types.
557
+ 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.
559
558
 
560
559
  ```typescript
561
560
  import { Type, Static, TSchema } from '@sinclair/typebox'
@@ -577,6 +576,7 @@ const T = Nullable(Type.String()) // const T = {
577
576
 
578
577
  type T = Static<typeof T> // type T = string | null
579
578
 
579
+
580
580
  //--------------------------------------------------------------------------------------------
581
581
  //
582
582
  // StringEnum<string[]>
@@ -596,7 +596,9 @@ type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
596
596
 
597
597
  ## Conditional Types
598
598
 
599
- Use `Conditional.Extends(...)` to create conditional mapped types.
599
+ 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.
600
+
601
+ The conditional module is provided as an optional import.
600
602
 
601
603
  ```typescript
602
604
  import { Conditional } from '@sinclair/typebox/conditional'
@@ -645,46 +647,56 @@ The following table shows the TypeBox mappings between TypeScript and JSON schem
645
647
 
646
648
  ## Values
647
649
 
648
- Use `Value.Create(...)` to generate values from types.
650
+ 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).
651
+
652
+ The value module is provided as an optional import.
649
653
 
650
654
  ```typescript
651
655
  import { Value } from '@sinclair/typebox/value'
652
- import { Type } from '@sinclair/typebox'
653
-
654
- const T = Type.Object({
655
- x: Type.Number({ default: 1 }),
656
- y: Type.Number()
657
- })
658
-
659
- const V = Value.Create(T) // const V = {
660
- // x: 1,
661
- // y: 0
662
- // }
663
656
  ```
664
- Use `Value.Cast(...)` to cast a value into a given type.
657
+ The following demonstrates its use.
665
658
  ```typescript
666
- import { Value } from '@sinclair/typebox/value'
667
- import { Type } from '@sinclair/typebox'
668
659
 
669
- const T = Type.Object({
670
- x: Type.Number(),
671
- y: Type.Number()
672
- })
673
660
 
674
- const A = Value.Cast(T, null) // const A = { x: 0, y: 0 }
661
+ const T = Type.Object({ x: Type.Number(), y: Type.Number() }, { additionalProperties: false })
662
+
663
+ //--------------------------------------------------------------------------------------------
664
+ //
665
+ // Use Value.Create(T) to create a value from T.
666
+ //
667
+ //--------------------------------------------------------------------------------------------
668
+
669
+ const V = Value.Create(T) // const V = { x: 0, y: 0 }
670
+
671
+ //--------------------------------------------------------------------------------------------
672
+ //
673
+ // Use Value.Check(T, ...) to check if a value is of type T.
674
+ //
675
+ //--------------------------------------------------------------------------------------------
676
+
677
+ const R = Value.Check(T, { x: 1 }) // const R = false
678
+
679
+ //--------------------------------------------------------------------------------------------
680
+ //
681
+ // Use Value.Cast(T, ...) to immutably cast a value into T.
682
+ //
683
+ //--------------------------------------------------------------------------------------------
684
+
685
+ const A = Value.Cast(T, null) // const A = { x: 0, y: 0 }
686
+
687
+ const B = Value.Cast(T, { x: 1 }) // const B = { x: 1, y: 0 }
688
+
689
+ const C = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const C = { x: 1, y: 2 }
675
690
 
676
- const B = Value.Cast(T, { x: 1 }) // const B = { x: 1, y: 0 }
677
691
 
678
- const C = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const C = { x: 1, y: 2 }
679
692
  ```
680
693
 
681
694
  ## Guards
682
695
 
683
- Use a `TypeGuard` to test if a value meets a TypeBox type specification. Guards can be helpful when reflecting types.
696
+ Use the guard module to test if values are TypeBox types.
684
697
 
685
698
  ```typescript
686
699
  import { TypeGuard } from '@sinclair/typebox/guard'
687
- import { Type } from '@sinclair/typebox'
688
700
 
689
701
  const T = Type.String()
690
702
 
@@ -692,7 +704,6 @@ if(TypeGuard.TString(T)) {
692
704
 
693
705
  // T is TString
694
706
  }
695
-
696
707
  ```
697
708
 
698
709
  ## Strict
@@ -789,14 +800,17 @@ Please refer to the official Ajv [documentation](https://ajv.js.org/guide/gettin
789
800
 
790
801
  ## Compiler
791
802
 
792
- TypeBox provides an optional high performance runtime type checker that can be used in applications that require extremely fast validation. This type checker is optimized for TypeBox types only whose schematics are known in advance. If defining custom schemas with `Type.Unsafe<T>` please consider Ajv.
803
+ 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.
793
804
 
794
- The following demonstrates its use.
805
+ The compiler module is provided as an optional import.
795
806
 
796
807
  ```typescript
797
808
  import { TypeCompiler } from '@sinclair/typebox/compiler'
798
- import { Type } from '@sinclair/typebox'
809
+ ```
810
+
811
+ Use the `Compile(...)` function to compile a type.
799
812
 
813
+ ```typescript
800
814
  const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObject<{
801
815
  x: Type.Number(), // x: TNumber;
802
816
  y: Type.Number(), // y: TNumber;
@@ -818,19 +832,16 @@ const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObje
818
832
  const value = { }
819
833
 
820
834
  const errors = [...C.Errors(value)] // const errors = [{
821
- // type: 14,
822
835
  // schema: { type: 'number' },
823
836
  // path: '/x',
824
837
  // value: undefined,
825
838
  // message: 'Expected number'
826
839
  // }, {
827
- // type: 14,
828
840
  // schema: { type: 'number' },
829
841
  // path: '/y',
830
842
  // value: undefined,
831
843
  // message: 'Expected number'
832
844
  // }, {
833
- // type: 14,
834
845
  // schema: { type: 'number' },
835
846
  // path: '/z',
836
847
  // value: undefined,
@@ -854,81 +865,95 @@ console.log(C.Code()) // return function check(va
854
865
 
855
866
  ## Benchmark
856
867
 
857
- This project maintains a set of benchmarks that measure Ajv and TypeCompiler compilation and validation performance. These benchmarks can be run locally by cloning this repository and running `npm run benchmark`. The results below show for Ajv version 8.11.0.
868
+ 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.
858
869
 
859
870
  For additional comparative benchmarks, please refer to [typescript-runtime-type-benchmarks](https://moltar.github.io/typescript-runtime-type-benchmarks/).
860
871
 
861
872
  ### Compile
862
873
 
863
- This benchmark measures compilation performance for varying types. You can review this benchmark [here](https://github.com/sinclairzx81/typebox/blob/master/benchmark/compile.ts).
874
+ 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).
864
875
 
865
876
  ```typescript
866
877
  ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┐
867
878
  │ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │
868
879
  ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┤
869
- │ Number │ 2000 │ ' 382 ms' │ ' 8 ms' │ ' 47.75 x' │
870
- │ String │ 2000 │ ' 305 ms' │ ' 7 ms' │ ' 43.57 x' │
871
- │ Boolean │ 2000 │ ' 305 ms' │ ' 5 ms' │ ' 61.00 x' │
872
- │ Null │ 2000 │ ' 253 ms' │ ' 5 ms' │ ' 50.60 x' │
873
- │ RegEx │ 2000 │ ' 475 ms' │ ' 10 ms' │ ' 47.50 x' │
874
- │ ObjectA │ 2000 │ ' 2812 ms' │ ' 44 ms' │ ' 63.91 x' │
875
- │ ObjectB │ 2000 │ ' 3045 ms' │ ' 34 ms' │ ' 89.56 x' │
876
- │ Tuple │ 2000 │ ' 1324 ms' │ ' 19 ms' │ ' 69.68 x' │
877
- │ Union │ 2000 │ ' 1347 ms' │ ' 26 ms' │ ' 51.81 x' │
878
- │ Vector4 │ 2000 │ ' 1635 ms' │ ' 18 ms' │ ' 90.83 x' │
879
- │ Matrix4 │ 2000 │ ' 928 ms' │ ' 10 ms' │ ' 92.80 x' │
880
- │ Literal_String │ 2000 │ ' 349 ms' │ ' 5 ms' │ ' 69.80 x' │
881
- │ Literal_Number │ 2000 │ ' 379 ms' │ ' 5 ms' │ ' 75.80 x' │
882
- │ Literal_Boolean │ 2000 │ ' 376 ms' │ ' 6 ms' │ ' 62.67 x' │
883
- │ Array_Number │ 2000 │ ' 733 ms' │ ' 10 ms' │ ' 73.30 x' │
884
- │ Array_String │ 2000 │ ' 766 ms' │ ' 8 ms' │ ' 95.75 x' │
885
- │ Array_Boolean │ 2000 │ ' 860 ms' │ ' 11 ms' │ ' 78.18 x' │
886
- │ Array_ObjectA │ 2000 │ ' 3668 ms' │ ' 42 ms' │ ' 87.33 x' │
887
- │ Array_ObjectB │ 2000 │ ' 3809 ms' │ ' 41 ms' │ ' 92.90 x' │
888
- │ Array_Tuple │ 2000 │ ' 2219 ms' │ ' 17 ms' │ ' 130.53 x' │
889
- │ Array_Union │ 2000 │ ' 1709 ms' │ ' 26 ms' │ ' 65.73 x' │
890
- │ Array_Vector4 │ 2000 │ ' 2301 ms' │ ' 18 ms' │ ' 127.83 x' │
891
- │ Array_Matrix4 │ 2000 │ ' 1594 ms' │ ' 12 ms' │ ' 132.83 x' │
880
+ │ Number │ 2000 │ ' 399 ms' │ ' 9 ms' │ ' 44.33 x' │
881
+ │ String │ 2000 │ ' 306 ms' │ ' 8 ms' │ ' 38.25 x' │
882
+ │ Boolean │ 2000 │ ' 315 ms' │ ' 5 ms' │ ' 63.00 x' │
883
+ │ Null │ 2000 │ ' 255 ms' │ ' 6 ms' │ ' 42.50 x' │
884
+ │ RegEx │ 2000 │ ' 478 ms' │ ' 10 ms' │ ' 47.80 x' │
885
+ │ ObjectA │ 2000 │ ' 2850 ms' │ ' 39 ms' │ ' 73.08 x' │
886
+ │ ObjectB │ 2000 │ ' 3027 ms' │ ' 34 ms' │ ' 89.03 x' │
887
+ │ Tuple │ 2000 │ ' 1374 ms' │ ' 27 ms' │ ' 50.89 x' │
888
+ │ Union │ 2000 │ ' 1307 ms' │ ' 22 ms' │ ' 59.41 x' │
889
+ │ Vector4 │ 2000 │ ' 1568 ms' │ ' 17 ms' │ ' 92.24 x' │
890
+ │ Matrix4 │ 2000 │ ' 911 ms' │ ' 11 ms' │ ' 82.82 x' │
891
+ │ Literal_String │ 2000 │ ' 332 ms' │ ' 8 ms' │ ' 41.50 x' │
892
+ │ Literal_Number │ 2000 │ ' 363 ms' │ ' 8 ms' │ ' 45.38 x' │
893
+ │ Literal_Boolean │ 2000 │ ' 360 ms' │ ' 5 ms' │ ' 72.00 x' │
894
+ │ Array_Number │ 2000 │ ' 704 ms' │ ' 6 ms' │ ' 117.33 x' │
895
+ │ Array_String │ 2000 │ ' 745 ms' │ ' 11 ms' │ ' 67.73 x' │
896
+ │ Array_Boolean │ 2000 │ ' 781 ms' │ ' 7 ms' │ ' 111.57 x' │
897
+ │ Array_ObjectA │ 2000 │ ' 3552 ms' │ ' 31 ms' │ ' 114.58 x' │
898
+ │ Array_ObjectB │ 2000 │ ' 3738 ms' │ ' 33 ms' │ ' 113.27 x' │
899
+ │ Array_Tuple │ 2000 │ ' 2336 ms' │ ' 16 ms' │ ' 146.00 x' │
900
+ │ Array_Union │ 2000 │ ' 1758 ms' │ ' 20 ms' │ ' 87.90 x' │
901
+ │ Array_Vector4 │ 2000 │ ' 2305 ms' │ ' 16 ms' │ ' 144.06 x' │
902
+ │ Array_Matrix4 │ 2000 │ ' 1635 ms' │ ' 11 ms' │ ' 148.64 x' │
892
903
  └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┘
893
904
  ```
894
905
 
895
906
  ### Validate
896
907
 
897
- This benchmark measures validation performance for varying types. You can review this benchmark [here](https://github.com/sinclairzx81/typebox/blob/master/benchmark/check.ts).
908
+ 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).
898
909
 
899
910
  ```typescript
900
- ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┐
901
- │ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │
902
- ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┤
903
- │ Number │ 4000000 │ ' 18 ms' │ ' 16 ms' │ ' 1.13 x' │
904
- │ String │ 4000000 │ ' 74 ms' │ ' 43 ms' │ ' 1.72 x' │
905
- │ Boolean │ 4000000 │ ' 71 ms' │ ' 37 ms' │ ' 1.92 x' │
906
- │ Null │ 4000000 │ ' 70 ms' │ ' 37 ms' │ ' 1.89 x' │
907
- │ RegEx │ 4000000 │ ' 175 ms' │ ' 153 ms' │ ' 1.14 x' │
908
- │ ObjectA │ 4000000 │ ' 124 ms' │ ' 87 ms' │ ' 1.43 x' │
909
- │ ObjectB │ 4000000 │ ' 215 ms' │ ' 143 ms' │ ' 1.50 x' │
910
- │ Tuple │ 4000000 │ ' 101 ms' │ ' 51 ms' │ ' 1.98 x' │
911
- │ Union │ 4000000 │ ' 108 ms' │ ' 51 ms' │ ' 2.12 x' │
912
- │ Recursive │ 4000000 │ ' 1647 ms' │ ' 626 ms' │ ' 2.63 x' │
913
- │ Vector4 │ 4000000 │ ' 83 ms' │ ' 41 ms' │ ' 2.02 x' │
914
- │ Matrix4 │ 4000000 │ ' 154 ms' │ ' 105 ms' │ ' 1.47 x' │
915
- │ Literal_String │ 4000000 │ ' 101 ms' │ ' 37 ms' │ ' 2.73 x' │
916
- │ Literal_Number │ 4000000 │ ' 69 ms' │ ' 35 ms' │ ' 1.97 x' │
917
- │ Literal_Boolean │ 4000000 │ ' 71 ms' │ ' 35 ms' │ ' 2.03 x' │
918
- │ Array_Number │ 4000000 │ ' 117 ms' │ ' 61 ms' │ ' 1.92 x' │
919
- │ Array_String │ 4000000 │ ' 116 ms' │ ' 73 ms' │ ' 1.59 x' │
920
- │ Array_Boolean │ 4000000 │ ' 129 ms' │ ' 89 ms' │ ' 1.45 x' │
921
- │ Array_ObjectA │ 4000000 │ ' 10582 ms' │ ' 6854 ms' │ ' 1.54 x' │
922
- │ Array_ObjectB │ 4000000 │ ' 11539 ms' │ ' 8224 ms' │ ' 1.40 x' │
923
- │ Array_Tuple │ 4000000 │ ' 362 ms' │ ' 282 ms' │ ' 1.28 x' │
924
- │ Array_Union │ 4000000 │ ' 950 ms' │ ' 355 ms' │ ' 2.68 x' │
925
- │ Array_Recursive │ 4000000 │ ' 28047 ms' │ ' 9567 ms' │ ' 2.93 x' │
926
- │ Array_Vector4 │ 4000000 │ ' 372 ms' │ ' 200 ms' │ ' 1.86 x' │
927
- │ Array_Matrix4 │ 4000000 │ ' 1521 ms' │ ' 1244 ms' │ ' 1.22 x' │
928
- └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┘
911
+ ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
912
+ │ (index) │ Iterations │ ValueCheck │ Ajv │ TypeCompiler │ Performance │
913
+ ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┼──────────────┤
914
+ │ Number │ 1000000 │ ' 31 ms' │ ' 6 ms' │ ' 5 ms' │ ' 1.20 x' │
915
+ │ String │ 1000000 │ ' 26 ms' │ ' 22 ms' │ ' 12 ms' │ ' 1.83 x' │
916
+ │ Boolean │ 1000000 │ ' 21 ms' │ ' 22 ms' │ ' 11 ms' │ ' 2.00 x' │
917
+ │ Null │ 1000000 │ ' 25 ms' │ ' 24 ms' │ ' 9 ms' │ ' 2.67 x' │
918
+ │ RegEx │ 1000000 │ ' 166 ms' │ ' 45 ms' │ ' 38 ms' │ ' 1.18 x' │
919
+ │ ObjectA │ 1000000 │ ' 535 ms' │ ' 36 ms' │ ' 22 ms' │ ' 1.64 x' │
920
+ │ ObjectB │ 1000000 │ ' 957 ms' │ ' 49 ms' │ ' 37 ms' │ ' 1.32 x' │
921
+ │ Tuple │ 1000000 │ ' 112 ms' │ ' 24 ms' │ ' 14 ms' │ ' 1.71 x' │
922
+ │ Union │ 1000000 │ ' 304 ms' │ ' 25 ms' │ ' 14 ms' │ ' 1.79 x' │
923
+ │ Recursive │ 1000000 │ ' 2986 ms' │ ' 391 ms' │ ' 164 ms' │ ' 2.38 x' │
924
+ │ Vector4 │ 1000000 │ ' 145 ms' │ ' 22 ms' │ ' 13 ms' │ ' 1.69 x' │
925
+ │ Matrix4 │ 1000000 │ ' 575 ms' │ ' 39 ms' │ ' 29 ms' │ ' 1.34 x' │
926
+ │ Literal_String │ 1000000 │ ' 44 ms' │ ' 18 ms' │ ' 10 ms' │ ' 1.80 x' │
927
+ │ Literal_Number │ 1000000 │ ' 46 ms' │ ' 19 ms' │ ' 9 ms' │ ' 2.11 x' │
928
+ │ Literal_Boolean │ 1000000 │ ' 47 ms' │ ' 19 ms' │ ' 9 ms' │ ' 2.11 x' │
929
+ │ Array_Number │ 1000000 │ ' 398 ms' │ ' 30 ms' │ ' 17 ms' │ ' 1.76 x' │
930
+ │ Array_String │ 1000000 │ ' 438 ms' │ ' 30 ms' │ ' 20 ms' │ ' 1.50 x' │
931
+ │ Array_Boolean │ 1000000 │ ' 443 ms' │ ' 37 ms' │ ' 24 ms' │ ' 1.54 x' │
932
+ │ Array_ObjectA │ 1000000 │ ' 13702 ms' │ ' 2649 ms' │ ' 1673 ms' │ ' 1.58 x' │
933
+ │ Array_ObjectB │ 1000000 │ ' 16091 ms' │ ' 2964 ms' │ ' 2032 ms' │ ' 1.46 x' │
934
+ │ Array_Tuple │ 1000000 │ ' 1665 ms' │ ' 92 ms' │ ' 70 ms' │ ' 1.31 x' │
935
+ │ Array_Union │ 1000000 │ ' 4631 ms' │ ' 220 ms' │ ' 88 ms' │ ' 2.50 x' │
936
+ │ Array_Recursive │ 1000000 │ ' 53745 ms' │ ' 6891 ms' │ ' 2744 ms' │ ' 2.51 x' │
937
+ │ Array_Vector4 │ 1000000 │ ' 2156 ms' │ ' 105 ms' │ ' 55 ms' │ ' 1.91 x' │
938
+ │ Array_Matrix4 │ 1000000 │ ' 11686 ms' │ ' 388 ms' │ ' 330 ms' │ ' 1.18 x' │
939
+ └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
929
940
  ```
930
941
 
942
+ ### Compression
943
+
944
+ The following table lists esbuild compiled and minified sizes for each TypeBox module.
931
945
 
946
+ ```typescript
947
+ ┌──────────────────────┬────────────┬────────────┬─────────────┐
948
+ │ (index) │ Compiled │ Minified │ Compression │
949
+ ├──────────────────────┼────────────┼────────────┼─────────────┤
950
+ │ typebox/compiler │ ' 47 kb' │ ' 23 kb' │ '1.99 x' │
951
+ │ typebox/conditional │ ' 41 kb' │ ' 16 kb' │ '2.47 x' │
952
+ │ typebox/guard │ ' 20 kb' │ ' 9 kb' │ '2.08 x' │
953
+ │ typebox/value │ ' 55 kb' │ ' 25 kb' │ '2.15 x' │
954
+ │ typebox │ ' 11 kb' │ ' 5 kb' │ '1.91 x' │
955
+ └──────────────────────┴────────────┴────────────┴─────────────┘
956
+ ```
932
957
 
933
958
  ## Contribute
934
959