@sinclair/typebox 0.25.22 → 0.25.24

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.
@@ -263,6 +263,9 @@ var TypeCompiler;
263
263
  const propertySchema = schema.properties[propertyKey];
264
264
  if (schema.required && schema.required.includes(propertyKey)) {
265
265
  yield* Visit(propertySchema, memberExpression);
266
+ if (index_3.TypeExtends.Undefined(propertySchema)) {
267
+ yield `('${propertyKey}' in ${value})`;
268
+ }
266
269
  }
267
270
  else {
268
271
  const expression = CreateExpression(propertySchema, memberExpression);
package/errors/errors.js CHANGED
@@ -30,6 +30,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.ValueErrors = exports.ValueErrorsUnknownTypeError = exports.ValueErrorType = void 0;
31
31
  const Types = require("../typebox");
32
32
  const index_1 = require("../system/index");
33
+ const extends_1 = require("../guard/extends");
33
34
  const index_2 = require("../format/index");
34
35
  const index_3 = require("../custom/index");
35
36
  const index_4 = require("../hash/index");
@@ -269,6 +270,9 @@ var ValueErrors;
269
270
  const propertySchema = schema.properties[propertyKey];
270
271
  if (schema.required && schema.required.includes(propertyKey)) {
271
272
  yield* Visit(propertySchema, references, `${path}/${propertyKey}`, value[propertyKey]);
273
+ if (extends_1.TypeExtends.Undefined(schema) && !(propertyKey in value)) {
274
+ yield { type: ValueErrorType.ObjectRequiredProperties, schema: propertySchema, path: `${path}/${propertyKey}`, value: undefined, message: `Expected required property` };
275
+ }
272
276
  }
273
277
  else {
274
278
  if (value[propertyKey] !== undefined) {
@@ -0,0 +1,10 @@
1
+ import * as Types from '../typebox';
2
+ export declare namespace TypeExtends {
3
+ /**
4
+ * This function returns true if the given schema is undefined, either directly or
5
+ * through union composition. This check is required on object property types of
6
+ * undefined, where an additional `'x' in value` check is required to determine
7
+ * the keys existence.
8
+ */
9
+ function Undefined(schema: Types.TSchema): boolean;
10
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ /*--------------------------------------------------------------------------
3
+
4
+ @sinclair/typebox/guard
5
+
6
+ The MIT License (MIT)
7
+
8
+ Copyright (c) 2017-2023 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, dTribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in
18
+ all copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26
+ THE SOFTWARE.
27
+
28
+ ---------------------------------------------------------------------------*/
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.TypeExtends = void 0;
31
+ const Types = require("../typebox");
32
+ var TypeExtends;
33
+ (function (TypeExtends) {
34
+ /**
35
+ * This function returns true if the given schema is undefined, either directly or
36
+ * through union composition. This check is required on object property types of
37
+ * undefined, where an additional `'x' in value` check is required to determine
38
+ * the keys existence.
39
+ */
40
+ function Undefined(schema) {
41
+ if (schema[Types.Kind] === 'Undefined')
42
+ return true;
43
+ if (schema[Types.Kind] === 'Union') {
44
+ const union = schema;
45
+ return union.anyOf.some((schema) => Undefined(schema));
46
+ }
47
+ return false;
48
+ }
49
+ TypeExtends.Undefined = Undefined;
50
+ })(TypeExtends = exports.TypeExtends || (exports.TypeExtends = {}));
package/guard/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from './guard';
2
+ export * from './extends';
package/guard/index.js CHANGED
@@ -42,3 +42,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
42
42
  };
43
43
  Object.defineProperty(exports, "__esModule", { value: true });
44
44
  __exportStar(require("./guard"), exports);
45
+ __exportStar(require("./extends"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.25.22",
3
+ "version": "0.25.24",
4
4
  "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
package/readme.md CHANGED
@@ -19,17 +19,17 @@
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'
@@ -64,7 +64,7 @@ type T = Static<typeof T> // type T = {
64
64
 
65
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.
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 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.
68
68
 
69
69
  License MIT
70
70
 
@@ -96,8 +96,8 @@ License MIT
96
96
  - [Errors](#values-errors)
97
97
  - [Pointer](#values-pointer)
98
98
  - [TypeCheck](#typecheck)
99
- - [TypeCompiler](#typecheck-typecompiler)
100
99
  - [Ajv](#typecheck-ajv)
100
+ - [TypeCompiler](#typecheck-typecompiler)
101
101
  - [TypeSystem](#typecheck)
102
102
  - [Types](#typesystem-types)
103
103
  - [Formats](#typesystem-formats)
@@ -933,17 +933,58 @@ ValuePointer.Set(A, '/z', 1) // const A = { x: 1, y: 1,
933
933
 
934
934
  ## TypeCheck
935
935
 
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.
936
+ TypeBox constructs JSON Schema draft 6 compliant schematics and can be used with any validator that supports this specification. In JavaScript, an ideal validator to use is Ajv which supports draft 6 as well as more recent revisions to the specification. In addition to Ajv, TypeBox provides an optional built in type compiler which can offer faster runtime type compilation, as well as providing high performance data validation for TypeBox types only.
937
937
 
938
938
  The following sections detail using these validators.
939
939
 
940
+ <a name='typecheck-ajv'></a>
941
+
942
+ ## Ajv
943
+
944
+ The following shows the recommended setup for Ajv.
945
+
946
+ ```bash
947
+ $ npm install ajv ajv-formats --save
948
+ ```
949
+
950
+ ```typescript
951
+ import { Type } from '@sinclair/typebox'
952
+ import addFormats from 'ajv-formats'
953
+ import Ajv from 'ajv'
954
+
955
+ const ajv = addFormats(new Ajv({}), [
956
+ 'date-time',
957
+ 'time',
958
+ 'date',
959
+ 'email',
960
+ 'hostname',
961
+ 'ipv4',
962
+ 'ipv6',
963
+ 'uri',
964
+ 'uri-reference',
965
+ 'uuid',
966
+ 'uri-template',
967
+ 'json-pointer',
968
+ 'relative-json-pointer',
969
+ 'regex'
970
+ ])
971
+
972
+ const C = ajv.compile(Type.Object({
973
+ x: Type.Number(),
974
+ y: Type.Number(),
975
+ z: Type.Number()
976
+ }))
977
+
978
+ const R = C({ x: 1, y: 2, z: 3 }) // const R = true
979
+ ```
980
+
940
981
  <a name='typecheck-typecompiler'></a>
941
982
 
942
983
  ### TypeCompiler
943
984
 
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.
985
+ The TypeCompiler is a Just-In-Time (JIT) runtime compiler that can be used to convert TypeBox types into fast validation routines. This compiler is specifically tuned for fast compilation and validation for TypeBox types only.
945
986
 
946
- The compiler module is provided as an optional import.
987
+ The TypeCompiler is provided as an optional import.
947
988
 
948
989
  ```typescript
949
990
  import { TypeCompiler } from '@sinclair/typebox/compiler'
@@ -961,7 +1002,7 @@ const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObje
961
1002
  const R = C.Check({ x: 1, y: 2, z: 3 }) // const R = true
962
1003
  ```
963
1004
 
964
- Validation errors can be read with the `Errors(...)` function.
1005
+ Use `Errors(...)` to generate diagnostics for a value. The `Errors(...)` function will run an exhaustive check across the value and yield any error found. For performance, this function should only be called after failed `Check(...)`.
965
1006
 
966
1007
  ```typescript
967
1008
  const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObject<{
@@ -1002,141 +1043,11 @@ console.log(C.Code()) // return function check(va
1002
1043
  // }
1003
1044
  ```
1004
1045
 
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.
1010
-
1011
- ```bash
1012
- $ npm install ajv ajv-formats --save
1013
- ```
1014
-
1015
- <details>
1016
-
1017
- <summary>
1018
- <strong>Standard Ajv Configuration</strong>
1019
- <p>Expand for Standard Type Set Configuration</p>
1020
- </summary>
1021
-
1022
- ```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 })
1053
- ```
1054
-
1055
- </details>
1056
-
1057
- <details>
1058
-
1059
- <summary>
1060
- <strong>Extended Ajv Configuration</strong>
1061
- <p>Expand for Extended Type Set Configuration</p>
1062
- </summary>
1063
-
1064
- ```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
- }
1118
-
1119
- const ajv = createAjv()
1120
-
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
1129
- })
1130
- ```
1131
-
1132
- </details>
1133
-
1134
-
1135
1046
  <a name='typesystem'></a>
1136
1047
 
1137
1048
  ## TypeSystem
1138
1049
 
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.
1050
+ TypeBox provides an extensible TypeSystem module that enables developers to define additional types above and beyond the built in type set. This module also allows developers to define custom string formats as well as override certain type checking behaviours.
1140
1051
 
1141
1052
  The TypeSystem module is provided as an optional import.
1142
1053
 
@@ -1148,7 +1059,7 @@ import { TypeSystem } from '@sinclair/typebox/system'
1148
1059
 
1149
1060
  ### Types
1150
1061
 
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`.
1062
+ Use the `CreateType(...)` function to specify 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`.
1152
1063
 
1153
1064
  ```typescript
1154
1065
  //--------------------------------------------------------------------------------------------
@@ -1233,29 +1144,29 @@ This benchmark measures compilation performance for varying types. You can revie
1233
1144
  ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┐
1234
1145
  │ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │
1235
1146
  ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┤
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' │
1147
+ │ Number │ 2000 │ ' 451 ms' │ ' 16 ms' │ ' 28.19 x' │
1148
+ │ String │ 2000 │ ' 338 ms' │ ' 14 ms' │ ' 24.14 x' │
1149
+ │ Boolean │ 2000 │ ' 297 ms' │ ' 13 ms' │ ' 22.85 x' │
1150
+ │ Null │ 2000 │ ' 265 ms' │ ' 8 ms' │ ' 33.13 x' │
1151
+ │ RegEx │ 2000 │ ' 492 ms' │ ' 18 ms' │ ' 27.33 x' │
1152
+ │ ObjectA │ 2000 │ ' 2744 ms' │ ' 55 ms' │ ' 49.89 x' │
1153
+ │ ObjectB │ 2000 │ ' 3005 ms' │ ' 44 ms' │ ' 68.30 x' │
1154
+ │ Tuple │ 2000 │ ' 1283 ms' │ ' 26 ms' │ ' 49.35 x' │
1155
+ │ Union │ 2000 │ ' 1263 ms' │ ' 27 ms' │ ' 46.78 x' │
1156
+ │ Vector4 │ 2000 │ ' 1622 ms' │ ' 23 ms' │ ' 70.52 x' │
1157
+ │ Matrix4 │ 2000 │ ' 888 ms' │ ' 12 ms' │ ' 74.00 x' │
1158
+ │ Literal_String │ 2000 │ ' 344 ms' │ ' 14 ms' │ ' 24.57 x' │
1159
+ │ Literal_Number │ 2000 │ ' 389 ms' │ ' 8 ms' │ ' 48.63 x' │
1160
+ │ Literal_Boolean │ 2000 │ ' 374 ms' │ ' 9 ms' │ ' 41.56 x' │
1161
+ │ Array_Number │ 2000 │ ' 710 ms' │ ' 12 ms' │ ' 59.17 x' │
1162
+ │ Array_String │ 2000 │ ' 739 ms' │ ' 9 ms' │ ' 82.11 x' │
1163
+ │ Array_Boolean │ 2000 │ ' 732 ms' │ ' 7 ms' │ ' 104.57 x' │
1164
+ │ Array_ObjectA │ 2000 │ ' 3733 ms' │ ' 42 ms' │ ' 88.88 x' │
1165
+ │ Array_ObjectB │ 2000 │ ' 3602 ms' │ ' 42 ms' │ ' 85.76 x' │
1166
+ │ Array_Tuple │ 2000 │ ' 2204 ms' │ ' 20 ms' │ ' 110.20 x' │
1167
+ │ Array_Union │ 2000 │ ' 1533 ms' │ ' 24 ms' │ ' 63.88 x' │
1168
+ │ Array_Vector4 │ 2000 │ ' 2263 ms' │ ' 21 ms' │ ' 107.76 x' │
1169
+ │ Array_Matrix4 │ 2000 │ ' 1576 ms' │ ' 14 ms' │ ' 112.57 x' │
1259
1170
  └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┘
1260
1171
  ```
1261
1172
 
@@ -1269,31 +1180,31 @@ This benchmark measures validation performance for varying types. You can review
1269
1180
  ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
1270
1181
  │ (index) │ Iterations │ ValueCheck │ Ajv │ TypeCompiler │ Performance │
1271
1182
  ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┼──────────────┤
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' │
1183
+ │ Number │ 1000000 │ ' 30 ms' │ ' 7 ms' │ ' 6 ms' │ ' 1.17 x' │
1184
+ │ String │ 1000000 │ ' 23 ms' │ ' 21 ms' │ ' 11 ms' │ ' 1.91 x' │
1185
+ │ Boolean │ 1000000 │ ' 22 ms' │ ' 21 ms' │ ' 10 ms' │ ' 2.10 x' │
1186
+ │ Null │ 1000000 │ ' 27 ms' │ ' 20 ms' │ ' 10 ms' │ ' 2.00 x' │
1187
+ │ RegEx │ 1000000 │ ' 163 ms' │ ' 47 ms' │ ' 38 ms' │ ' 1.24 x' │
1188
+ │ ObjectA │ 1000000 │ ' 654 ms' │ ' 41 ms' │ ' 24 ms' │ ' 1.71 x' │
1189
+ │ ObjectB │ 1000000 │ ' 1173 ms' │ ' 59 ms' │ ' 41 ms' │ ' 1.44 x' │
1190
+ │ Tuple │ 1000000 │ ' 124 ms' │ ' 24 ms' │ ' 17 ms' │ ' 1.41 x' │
1191
+ │ Union │ 1000000 │ ' 332 ms' │ ' 26 ms' │ ' 16 ms' │ ' 1.63 x' │
1192
+ │ Recursive │ 1000000 │ ' 3129 ms' │ ' 412 ms' │ ' 102 ms' │ ' 4.04 x' │
1193
+ │ Vector4 │ 1000000 │ ' 147 ms' │ ' 26 ms' │ ' 13 ms' │ ' 2.00 x' │
1194
+ │ Matrix4 │ 1000000 │ ' 576 ms' │ ' 41 ms' │ ' 28 ms' │ ' 1.46 x' │
1195
+ │ Literal_String │ 1000000 │ ' 51 ms' │ ' 21 ms' │ ' 10 ms' │ ' 2.10 x' │
1196
+ │ Literal_Number │ 1000000 │ ' 47 ms' │ ' 21 ms' │ ' 11 ms' │ ' 1.91 x' │
1197
+ │ Literal_Boolean │ 1000000 │ ' 47 ms' │ ' 21 ms' │ ' 10 ms' │ ' 2.10 x' │
1198
+ │ Array_Number │ 1000000 │ ' 490 ms' │ ' 33 ms' │ ' 18 ms' │ ' 1.83 x' │
1199
+ │ Array_String │ 1000000 │ ' 502 ms' │ ' 31 ms' │ ' 25 ms' │ ' 1.24 x' │
1200
+ │ Array_Boolean │ 1000000 │ ' 465 ms' │ ' 33 ms' │ ' 27 ms' │ ' 1.22 x' │
1201
+ │ Array_ObjectA │ 1000000 │ ' 15463 ms' │ ' 2470 ms' │ ' 2052 ms' │ ' 1.20 x' │
1202
+ │ Array_ObjectB │ 1000000 │ ' 18047 ms' │ ' 2497 ms' │ ' 2348 ms' │ ' 1.06 x' │
1203
+ │ Array_Tuple │ 1000000 │ ' 1958 ms' │ ' 99 ms' │ ' 77 ms' │ ' 1.29 x' │
1204
+ │ Array_Union │ 1000000 │ ' 5348 ms' │ ' 254 ms' │ ' 89 ms' │ ' 2.85 x' │
1205
+ │ Array_Recursive │ 1000000 │ ' 54643 ms' │ ' 8870 ms' │ ' 1158 ms' │ ' 7.66 x' │
1206
+ │ Array_Vector4 │ 1000000 │ ' 2724 ms' │ ' 105 ms' │ ' 48 ms' │ ' 2.19 x' │
1207
+ │ Array_Matrix4 │ 1000000 │ ' 13821 ms' │ ' 437 ms' │ ' 266 ms' │ ' 1.64 x' │
1297
1208
  └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
1298
1209
  ```
1299
1210
 
@@ -1307,14 +1218,15 @@ The following table lists esbuild compiled and minified sizes for each TypeBox m
1307
1218
  ┌──────────────────────┬────────────┬────────────┬─────────────┐
1308
1219
  │ (index) │ Compiled │ Minified │ Compression │
1309
1220
  ├──────────────────────┼────────────┼────────────┼─────────────┤
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' │
1221
+ │ typebox/compiler │ ' 65.4 kb' │ ' 32.2 kb' │ '2.03 x' │
1222
+ │ typebox/conditional │ ' 45.5 kb' │ ' 18.6 kb' │ '2.45 x' │
1223
+ │ typebox/custom │ ' 0.6 kb' │ ' 0.2 kb' │ '2.61 x' │
1224
+ │ typebox/format │ ' 0.6 kb' │ ' 0.2 kb' │ '2.66 x' │
1225
+ │ typebox/guard │ ' 23.8 kb' │ ' 11.4 kb' │ '2.08 x' │
1226
+ │ typebox/hash │ ' 4.2 kb' │ ' 1.8 kb' │ '2.30 x' │
1227
+ │ typebox/system │ ' 14.0 kb' │ ' 7.1 kb' │ '1.96 x' │
1228
+ │ typebox/value │ ' 90.0 kb' │ ' 41.8 kb' │ '2.15 x' │
1229
+ │ typebox │ ' 12.0 kb' │ ' 6.4 kb' │ '1.89 x' │
1318
1230
  └──────────────────────┴────────────┴────────────┴─────────────┘
1319
1231
  ```
1320
1232
 
package/typebox.d.ts CHANGED
@@ -172,17 +172,12 @@ export type OptionalPropertyKeys<T extends TProperties> = {
172
172
  [K in keyof T]: T[K] extends TOptional<TSchema> ? K : never;
173
173
  }[keyof T];
174
174
  export type RequiredPropertyKeys<T extends TProperties> = keyof Omit<T, ReadonlyOptionalPropertyKeys<T> | ReadonlyPropertyKeys<T> | OptionalPropertyKeys<T>>;
175
- export type PropertiesReduce<T extends TProperties, P extends unknown[]> = {
176
- readonly [K in ReadonlyOptionalPropertyKeys<T>]?: Static<T[K], P>;
177
- } & {
178
- readonly [K in ReadonlyPropertyKeys<T>]: Static<T[K], P>;
179
- } & {
180
- [K in OptionalPropertyKeys<T>]?: Static<T[K], P>;
181
- } & {
182
- [K in RequiredPropertyKeys<T>]: Static<T[K], P>;
183
- } extends infer R ? {
184
- [K in keyof R]: R[K];
175
+ export type PropertiesReducer<T extends TProperties, R extends Record<keyof any, unknown>> = (Readonly<Partial<Pick<R, ReadonlyOptionalPropertyKeys<T>>>> & Readonly<Pick<R, ReadonlyPropertyKeys<T>>> & Partial<Pick<R, OptionalPropertyKeys<T>>> & Required<Pick<R, RequiredPropertyKeys<T>>>) extends infer O ? {
176
+ [K in keyof O]: O[K];
185
177
  } : never;
178
+ export type PropertiesReduce<T extends TProperties, P extends unknown[]> = PropertiesReducer<T, {
179
+ [K in keyof T]: Static<T[K], P>;
180
+ }>;
186
181
  export type TRecordProperties<K extends TUnion<TLiteral[]>, T extends TSchema> = Static<K> extends string ? {
187
182
  [X in Static<K>]: T;
188
183
  } : never;
package/value/cast.js CHANGED
@@ -308,9 +308,6 @@ var ValueCast;
308
308
  }
309
309
  return result;
310
310
  }
311
- function Recursive(schema, references, value) {
312
- throw new ValueCastRecursiveTypeError(schema);
313
- }
314
311
  function Ref(schema, references, value) {
315
312
  const reference = references.find((reference) => reference.$id === schema.$ref);
316
313
  if (reference === undefined)
@@ -386,8 +383,6 @@ var ValueCast;
386
383
  return Promise(anySchema, anyReferences, value);
387
384
  case 'Record':
388
385
  return Record(anySchema, anyReferences, value);
389
- case 'Rec':
390
- return Recursive(anySchema, anyReferences, value);
391
386
  case 'Ref':
392
387
  return Ref(anySchema, anyReferences, value);
393
388
  case 'Self':
package/value/check.js CHANGED
@@ -30,6 +30,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.ValueCheck = exports.ValueCheckUnknownTypeError = void 0;
31
31
  const Types = require("../typebox");
32
32
  const index_1 = require("../system/index");
33
+ const extends_1 = require("../guard/extends");
33
34
  const index_2 = require("../format/index");
34
35
  const index_3 = require("../custom/index");
35
36
  const index_4 = require("../hash/index");
@@ -42,9 +43,15 @@ class ValueCheckUnknownTypeError extends Error {
42
43
  exports.ValueCheckUnknownTypeError = ValueCheckUnknownTypeError;
43
44
  var ValueCheck;
44
45
  (function (ValueCheck) {
46
+ // --------------------------------------------------------
47
+ // Guards
48
+ // --------------------------------------------------------
45
49
  function IsNumber(value) {
46
50
  return typeof value === 'number' && !isNaN(value);
47
51
  }
52
+ // --------------------------------------------------------
53
+ // Guards
54
+ // --------------------------------------------------------
48
55
  function Any(schema, references, value) {
49
56
  return true;
50
57
  }
@@ -207,6 +214,9 @@ var ValueCheck;
207
214
  if (!Visit(propertySchema, references, value[propertyKey])) {
208
215
  return false;
209
216
  }
217
+ if (extends_1.TypeExtends.Undefined(propertySchema)) {
218
+ return propertyKey in value;
219
+ }
210
220
  }
211
221
  else {
212
222
  if (value[propertyKey] !== undefined) {
package/value/create.js CHANGED
@@ -195,14 +195,6 @@ var ValueCreate;
195
195
  return {};
196
196
  }
197
197
  }
198
- function Recursive(schema, references) {
199
- if (schema.default !== undefined) {
200
- return schema.default;
201
- }
202
- else {
203
- throw new Error('ValueCreate.Recursive: Recursive types require a default value');
204
- }
205
- }
206
198
  function Ref(schema, references) {
207
199
  if (schema.default !== undefined) {
208
200
  return schema.default;
@@ -354,8 +346,6 @@ var ValueCreate;
354
346
  return Promise(anySchema, anyReferences);
355
347
  case 'Record':
356
348
  return Record(anySchema, anyReferences);
357
- case 'Rec':
358
- return Recursive(anySchema, anyReferences);
359
349
  case 'Ref':
360
350
  return Ref(anySchema, anyReferences);
361
351
  case 'Self':