@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/compiler/compiler.d.ts +1 -1
- package/compiler/compiler.js +63 -87
- package/conditional/conditional.js +2 -2
- package/errors/errors.d.ts +1 -1
- package/errors/errors.js +53 -72
- package/guard/guard.d.ts +28 -22
- package/guard/guard.js +75 -22
- package/package.json +2 -2
- package/readme.md +122 -97
- package/value/cast.d.ts +1 -1
- package/value/cast.js +55 -71
- package/value/check.d.ts +1 -1
- package/value/check.js +53 -72
- package/value/create.d.ts +1 -1
- package/value/create.js +56 -71
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) &&
|
|
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
|
|
156
|
-
if (!
|
|
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) &&
|
|
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) &&
|
|
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.
|
|
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.
|
|
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
|
-
|
|
22
|
+
Node
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
$ npm install @sinclair/typebox --save
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Deno and ESM
|
|
29
29
|
|
|
30
30
|
```typescript
|
|
31
|
-
import { Static, Type } from 'https://
|
|
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
|
|
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
|
|
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]
|
|
510
|
-
.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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
805
|
+
The compiler module is provided as an optional import.
|
|
795
806
|
|
|
796
807
|
```typescript
|
|
797
808
|
import { TypeCompiler } from '@sinclair/typebox/compiler'
|
|
798
|
-
|
|
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 │ '
|
|
870
|
-
│ String │ 2000 │ '
|
|
871
|
-
│ Boolean │ 2000 │ '
|
|
872
|
-
│ Null │ 2000 │ '
|
|
873
|
-
│ RegEx │ 2000 │ '
|
|
874
|
-
│ ObjectA │ 2000 │ '
|
|
875
|
-
│ ObjectB │ 2000 │ '
|
|
876
|
-
│ Tuple │ 2000 │ '
|
|
877
|
-
│ Union │ 2000 │ '
|
|
878
|
-
│ Vector4 │ 2000 │ '
|
|
879
|
-
│ Matrix4 │ 2000 │ '
|
|
880
|
-
│ Literal_String │ 2000 │ '
|
|
881
|
-
│ Literal_Number │ 2000 │ '
|
|
882
|
-
│ Literal_Boolean │ 2000 │ '
|
|
883
|
-
│ Array_Number │ 2000 │ '
|
|
884
|
-
│ Array_String │ 2000 │ '
|
|
885
|
-
│ Array_Boolean │ 2000 │ '
|
|
886
|
-
│ Array_ObjectA │ 2000 │ '
|
|
887
|
-
│ Array_ObjectB │ 2000 │ '
|
|
888
|
-
│ Array_Tuple │ 2000 │ '
|
|
889
|
-
│ Array_Union │ 2000 │ '
|
|
890
|
-
│ Array_Vector4 │ 2000 │ '
|
|
891
|
-
│ Array_Matrix4 │ 2000 │ '
|
|
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 │
|
|
904
|
-
│ String │
|
|
905
|
-
│ Boolean │
|
|
906
|
-
│ Null │
|
|
907
|
-
│ RegEx │
|
|
908
|
-
│ ObjectA │
|
|
909
|
-
│ ObjectB │
|
|
910
|
-
│ Tuple │
|
|
911
|
-
│ Union │
|
|
912
|
-
│ Recursive │
|
|
913
|
-
│ Vector4 │
|
|
914
|
-
│ Matrix4 │
|
|
915
|
-
│ Literal_String │
|
|
916
|
-
│ Literal_Number │
|
|
917
|
-
│ Literal_Boolean │
|
|
918
|
-
│ Array_Number │
|
|
919
|
-
│ Array_String │
|
|
920
|
-
│ Array_Boolean │
|
|
921
|
-
│ Array_ObjectA │
|
|
922
|
-
│ Array_ObjectB │
|
|
923
|
-
│ Array_Tuple │
|
|
924
|
-
│ Array_Union │
|
|
925
|
-
│ Array_Recursive │
|
|
926
|
-
│ Array_Vector4 │
|
|
927
|
-
│ Array_Matrix4 │
|
|
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
|
|