@sinclair/typebox 0.30.4 → 0.31.0-dev-2
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 +22 -14
- package/compiler/compiler.js +119 -106
- package/compiler/index.d.ts +1 -1
- package/compiler/index.js +2 -1
- package/errors/errors.d.ts +56 -61
- package/errors/errors.js +222 -279
- package/package.json +5 -3
- package/readme.md +588 -507
- package/system/system.d.ts +34 -8
- package/system/system.js +214 -11
- package/typebox.d.ts +180 -106
- package/typebox.js +794 -907
- package/value/cast.d.ts +6 -12
- package/value/cast.js +81 -163
- package/value/check.d.ts +1 -5
- package/value/check.js +59 -103
- package/value/clone.js +6 -29
- package/value/convert.d.ts +2 -5
- package/value/convert.js +55 -106
- package/value/create.d.ts +6 -10
- package/value/create.js +54 -68
- package/value/delta.js +22 -22
- package/value/deref.d.ts +7 -0
- package/value/deref.js +46 -0
- package/value/equal.js +10 -10
- package/value/guard.js +1 -1
- package/value/hash.js +14 -14
- package/value/mutate.js +17 -17
- package/value/pointer.js +2 -2
- package/value/transform.d.ts +42 -0
- package/value/transform.js +512 -0
- package/value/value.d.ts +8 -0
- package/value/value.js +18 -0
package/readme.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<h1>TypeBox</h1>
|
|
4
4
|
|
|
5
|
-
<p>
|
|
5
|
+
<p>Json Schema Type Builder with Static Type Resolution for TypeScript</p>
|
|
6
6
|
|
|
7
7
|
<img src="https://github.com/sinclairzx81/typebox/blob/master/typebox.png?raw=true" />
|
|
8
8
|
|
|
@@ -25,37 +25,32 @@
|
|
|
25
25
|
$ npm install @sinclair/typebox --save
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
#### Deno
|
|
29
|
-
```typescript
|
|
30
|
-
import { Static, Type } from 'npm:@sinclair/typebox'
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
#### Esm
|
|
28
|
+
#### Esm + Deno
|
|
34
29
|
|
|
35
30
|
```typescript
|
|
36
|
-
import {
|
|
31
|
+
import { Type, Static } from 'https://esm.sh/@sinclair/typebox'
|
|
37
32
|
```
|
|
38
33
|
|
|
39
34
|
## Example
|
|
40
35
|
|
|
41
36
|
```typescript
|
|
42
|
-
import {
|
|
43
|
-
|
|
44
|
-
const T = Type.Object({
|
|
45
|
-
x: Type.Number(),
|
|
46
|
-
y: Type.Number(),
|
|
47
|
-
z: Type.Number()
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
type T = Static<typeof T>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
37
|
+
import { Type, Static } from '@sinclair/typebox'
|
|
38
|
+
|
|
39
|
+
const T = Type.Object({ // const T = {
|
|
40
|
+
x: Type.Number(), // type: 'object',
|
|
41
|
+
y: Type.Number(), // required: ['x', 'y', 'z'],
|
|
42
|
+
z: Type.Number() // properties: {
|
|
43
|
+
}) // x: { type: 'number' },
|
|
44
|
+
// y: { type: 'number' },
|
|
45
|
+
// z: { type: 'number' }
|
|
46
|
+
// }
|
|
47
|
+
// }
|
|
48
|
+
|
|
49
|
+
type T = Static<typeof T> // type T = {
|
|
50
|
+
// x: number,
|
|
51
|
+
// y: number,
|
|
52
|
+
// z: number
|
|
53
|
+
// }
|
|
59
54
|
```
|
|
60
55
|
|
|
61
56
|
|
|
@@ -63,9 +58,11 @@ type T = Static<typeof T> // type T = {
|
|
|
63
58
|
|
|
64
59
|
## Overview
|
|
65
60
|
|
|
66
|
-
TypeBox is a runtime type builder that creates
|
|
61
|
+
TypeBox is a runtime type builder that creates Json Schema objects that infer as TypeScript types. The schemas produced by this library are designed specifically to match the static type checking assertion rules of the TypeScript programming language. TypeBox offers a unified type that can be statically checked by TypeScript and runtime asserted using standard Json Schema validation.
|
|
67
62
|
|
|
68
|
-
|
|
63
|
+
TypeBox is built to be a runtime type system that is based on industry standard specifications for use in distributed systems. It has serializable and publishable types as standard, a fully extensible type system able to support multiple specifications, includes an extremely high performance runtime validator, offers various utilities for working with dynamic data and has detailed and customizable structured error reporting.
|
|
64
|
+
|
|
65
|
+
TypeBox can be used as a simple tool to build up complex schemas or integrated into applications and frameworks to validate data received over the wire.
|
|
69
66
|
|
|
70
67
|
License MIT
|
|
71
68
|
|
|
@@ -74,19 +71,19 @@ License MIT
|
|
|
74
71
|
- [Overview](#overview)
|
|
75
72
|
- [Usage](#usage)
|
|
76
73
|
- [Types](#types)
|
|
77
|
-
- [
|
|
78
|
-
- [
|
|
74
|
+
- [Json](#types-json)
|
|
75
|
+
- [JavaScript](#types-javascript)
|
|
79
76
|
- [Options](#types-options)
|
|
80
77
|
- [Properties](#types-properties)
|
|
81
78
|
- [Generics](#types-generics)
|
|
82
79
|
- [References](#types-references)
|
|
83
80
|
- [Recursive](#types-recursive)
|
|
84
81
|
- [Conditional](#types-conditional)
|
|
85
|
-
- [Template Literal](#types-
|
|
82
|
+
- [Template Literal](#types-templateliteral)
|
|
86
83
|
- [Indexed](#types-indexed)
|
|
87
|
-
- [Negated](#types-negated)
|
|
88
|
-
- [Intrinsic](#types-intrinsic)
|
|
89
84
|
- [Rest](#types-rest)
|
|
85
|
+
- [Transform](#types-transform)
|
|
86
|
+
- [Intrinsic](#types-intrinsic)
|
|
90
87
|
- [Guards](#types-guards)
|
|
91
88
|
- [Unsafe](#types-unsafe)
|
|
92
89
|
- [Strict](#types-strict)
|
|
@@ -96,6 +93,8 @@ License MIT
|
|
|
96
93
|
- [Check](#values-check)
|
|
97
94
|
- [Convert](#values-convert)
|
|
98
95
|
- [Cast](#values-cast)
|
|
96
|
+
- [Decode](#values-decode)
|
|
97
|
+
- [Encode](#values-decode)
|
|
99
98
|
- [Equal](#values-equal)
|
|
100
99
|
- [Hash](#values-hash)
|
|
101
100
|
- [Diff](#values-diff)
|
|
@@ -103,14 +102,19 @@ License MIT
|
|
|
103
102
|
- [Errors](#values-errors)
|
|
104
103
|
- [Mutate](#values-mutate)
|
|
105
104
|
- [Pointer](#values-pointer)
|
|
105
|
+
- [TypeRegistry](#typeregistry)
|
|
106
|
+
- [Type](#typeregistry-type)
|
|
107
|
+
- [Format](#typeregistry-format)
|
|
106
108
|
- [TypeCheck](#typecheck)
|
|
107
109
|
- [Ajv](#typecheck-ajv)
|
|
108
110
|
- [TypeCompiler](#typecheck-typecompiler)
|
|
109
111
|
- [TypeSystem](#typesystem)
|
|
110
112
|
- [Types](#typesystem-types)
|
|
111
113
|
- [Formats](#typesystem-formats)
|
|
114
|
+
- [Errors](#typesystem-errors)
|
|
112
115
|
- [Policies](#typesystem-policies)
|
|
113
116
|
- [Workbench](#workbench)
|
|
117
|
+
- [Codegen](#codegen)
|
|
114
118
|
- [Ecosystem](#ecosystem)
|
|
115
119
|
- [Benchmark](#benchmark)
|
|
116
120
|
- [Compile](#benchmark-compile)
|
|
@@ -125,7 +129,7 @@ License MIT
|
|
|
125
129
|
The following shows general usage.
|
|
126
130
|
|
|
127
131
|
```typescript
|
|
128
|
-
import {
|
|
132
|
+
import { Type, Static } from '@sinclair/typebox'
|
|
129
133
|
|
|
130
134
|
//--------------------------------------------------------------------------------------------
|
|
131
135
|
//
|
|
@@ -145,25 +149,25 @@ type T = {
|
|
|
145
149
|
//
|
|
146
150
|
//--------------------------------------------------------------------------------------------
|
|
147
151
|
|
|
148
|
-
const T = Type.Object({
|
|
149
|
-
id: Type.String(),
|
|
150
|
-
name: Type.String(),
|
|
151
|
-
timestamp: Type.Integer()
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
152
|
+
const T = Type.Object({ // const T = {
|
|
153
|
+
id: Type.String(), // type: 'object',
|
|
154
|
+
name: Type.String(), // properties: {
|
|
155
|
+
timestamp: Type.Integer() // id: {
|
|
156
|
+
}) // type: 'string'
|
|
157
|
+
// },
|
|
158
|
+
// name: {
|
|
159
|
+
// type: 'string'
|
|
160
|
+
// },
|
|
161
|
+
// timestamp: {
|
|
162
|
+
// type: 'integer'
|
|
163
|
+
// }
|
|
164
|
+
// },
|
|
165
|
+
// required: [
|
|
166
|
+
// 'id',
|
|
167
|
+
// 'name',
|
|
168
|
+
// 'timestamp'
|
|
169
|
+
// ]
|
|
170
|
+
// }
|
|
167
171
|
|
|
168
172
|
//--------------------------------------------------------------------------------------------
|
|
169
173
|
//
|
|
@@ -171,23 +175,23 @@ const T = Type.Object({ // const T = {
|
|
|
171
175
|
//
|
|
172
176
|
//--------------------------------------------------------------------------------------------
|
|
173
177
|
|
|
174
|
-
type T = Static<typeof T>
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
178
|
+
type T = Static<typeof T> // type T = {
|
|
179
|
+
// id: string,
|
|
180
|
+
// name: string,
|
|
181
|
+
// timestamp: number
|
|
182
|
+
// }
|
|
179
183
|
|
|
180
184
|
//--------------------------------------------------------------------------------------------
|
|
181
185
|
//
|
|
182
|
-
// ... then use the type both as
|
|
186
|
+
// ... then use the type both as Json Schema and as a TypeScript type.
|
|
183
187
|
//
|
|
184
188
|
//--------------------------------------------------------------------------------------------
|
|
185
189
|
|
|
186
190
|
import { Value } from '@sinclair/typebox/value'
|
|
187
191
|
|
|
188
|
-
function receive(value: T) {
|
|
192
|
+
function receive(value: T) { // ... as a Static Type
|
|
189
193
|
|
|
190
|
-
if(Value.Check(T, value)) {
|
|
194
|
+
if(Value.Check(T, value)) { // ... as a Json Schema
|
|
191
195
|
|
|
192
196
|
// ok...
|
|
193
197
|
}
|
|
@@ -198,17 +202,17 @@ function receive(value: T) { // ... as a Static Type
|
|
|
198
202
|
|
|
199
203
|
## Types
|
|
200
204
|
|
|
201
|
-
TypeBox types are
|
|
205
|
+
TypeBox types are Json Schema fragments that compose into more complex types. Each fragment is structured such that any Json Schema compliant validator can runtime assert a value the same way TypeScript will statically assert a type. TypeBox offers a set of Json Types which are used create Json Schema compliant schematics as well as a JavaScript type set used to create schematics for constructs native to JavaScript.
|
|
202
206
|
|
|
203
|
-
<a name='types-
|
|
207
|
+
<a name='types-json'></a>
|
|
204
208
|
|
|
205
|
-
###
|
|
209
|
+
### Json Types
|
|
206
210
|
|
|
207
|
-
The following table lists the
|
|
211
|
+
The following table lists the supported Json types. These types are fully compatible with the Json Schema Draft 7 specification.
|
|
208
212
|
|
|
209
213
|
```typescript
|
|
210
214
|
┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
|
|
211
|
-
│ TypeBox │ TypeScript │
|
|
215
|
+
│ TypeBox │ TypeScript │ Json Schema │
|
|
212
216
|
│ │ │ │
|
|
213
217
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
214
218
|
│ const T = Type.Any() │ type T = any │ const T = { } │
|
|
@@ -387,12 +391,6 @@ The following table lists the Standard TypeBox types. These types are fully comp
|
|
|
387
391
|
│ ) │ │ │
|
|
388
392
|
│ │ │ │
|
|
389
393
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
390
|
-
│ const T = Type.Pattern('^xy$') │ type T = string │ const T = { │
|
|
391
|
-
│ │ │ type: 'string', │
|
|
392
|
-
│ │ │ pattern: '^xy$' │
|
|
393
|
-
│ │ │ } │
|
|
394
|
-
│ │ │ │
|
|
395
|
-
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
396
394
|
│ const U = Type.Union([ │ type U = 'open' | 'close' │ const T = { │
|
|
397
395
|
│ Type.Literal('open'), │ │ type: 'string', │
|
|
398
396
|
│ Type.Literal('close') │ type T = `on${U}` │ pattern: '^on(open|close)$' │
|
|
@@ -523,11 +521,11 @@ The following table lists the Standard TypeBox types. These types are fully comp
|
|
|
523
521
|
└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
|
|
524
522
|
```
|
|
525
523
|
|
|
526
|
-
<a name='types-
|
|
524
|
+
<a name='types-javascript'></a>
|
|
527
525
|
|
|
528
|
-
###
|
|
526
|
+
### JavaScript Types
|
|
529
527
|
|
|
530
|
-
TypeBox provides
|
|
528
|
+
TypeBox provides an extended type set that can be used to create schematics for common JavaScript constructs. These types can not be used with any standard Json Schema validator; but can be used to frame schematics for interfaces that may receive Json validated data. JavaScript types are prefixed with the `[JavaScript]` jsdoc comment for convenience. The following table lists the supported types.
|
|
531
529
|
|
|
532
530
|
```typescript
|
|
533
531
|
┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
|
|
@@ -584,6 +582,12 @@ TypeBox provides several extended types that can be used to produce schematics f
|
|
|
584
582
|
│ │ │ } │
|
|
585
583
|
│ │ │ │
|
|
586
584
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
585
|
+
│ const T = Type.RegExp(/abc/) │ type T = string │ const T = { │
|
|
586
|
+
│ │ │ type: 'string' │
|
|
587
|
+
│ │ │ pattern: 'abc' │
|
|
588
|
+
│ │ │ } │
|
|
589
|
+
│ │ │ │
|
|
590
|
+
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
587
591
|
│ const T = Type.Uint8Array() │ type T = Uint8Array │ const T = { │
|
|
588
592
|
│ │ │ type: 'Uint8Array' │
|
|
589
593
|
│ │ │ } │
|
|
@@ -620,40 +624,40 @@ TypeBox provides several extended types that can be used to produce schematics f
|
|
|
620
624
|
|
|
621
625
|
### Options
|
|
622
626
|
|
|
623
|
-
You can pass
|
|
627
|
+
You can pass Json Schema options on the last argument of any type. Option hints specific to each type are provided for convenience.
|
|
624
628
|
|
|
625
629
|
```typescript
|
|
626
630
|
// String must be an email
|
|
627
|
-
const T = Type.String({
|
|
628
|
-
format: 'email'
|
|
629
|
-
})
|
|
630
|
-
|
|
631
|
+
const T = Type.String({ // const T = {
|
|
632
|
+
format: 'email' // type: 'string',
|
|
633
|
+
}) // format: 'email'
|
|
634
|
+
// }
|
|
631
635
|
|
|
632
636
|
// Number must be a multiple of 2
|
|
633
|
-
const T = Type.Number({
|
|
634
|
-
multipleOf: 2
|
|
635
|
-
})
|
|
636
|
-
|
|
637
|
+
const T = Type.Number({ // const T = {
|
|
638
|
+
multipleOf: 2 // type: 'number',
|
|
639
|
+
}) // multipleOf: 2
|
|
640
|
+
// }
|
|
637
641
|
|
|
638
642
|
// Array must have at least 5 integer values
|
|
639
|
-
const T = Type.Array(Type.Integer(), {
|
|
640
|
-
minItems: 5
|
|
641
|
-
})
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
643
|
+
const T = Type.Array(Type.Integer(), { // const T = {
|
|
644
|
+
minItems: 5 // type: 'array',
|
|
645
|
+
}) // minItems: 5,
|
|
646
|
+
// items: {
|
|
647
|
+
// type: 'integer'
|
|
648
|
+
// }
|
|
649
|
+
// }
|
|
646
650
|
```
|
|
647
651
|
|
|
648
652
|
<a name='types-properties'></a>
|
|
649
653
|
|
|
650
654
|
### Properties
|
|
651
655
|
|
|
652
|
-
Object properties can be modified with
|
|
656
|
+
Object properties can be modified with Readonly and Optional. The following table shows how these modifiers map between TypeScript and Json Schema.
|
|
653
657
|
|
|
654
658
|
```typescript
|
|
655
659
|
┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
|
|
656
|
-
│ TypeBox │ TypeScript │
|
|
660
|
+
│ TypeBox │ TypeScript │ Json Schema │
|
|
657
661
|
│ │ │ │
|
|
658
662
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
659
663
|
│ const T = Type.Object({ │ type T = { │ const T = { │
|
|
@@ -692,31 +696,31 @@ Object properties can be modified with `readonly` or `optional`. The following t
|
|
|
692
696
|
|
|
693
697
|
### Generic Types
|
|
694
698
|
|
|
695
|
-
Generic types
|
|
699
|
+
Generic types can be created with generic functions. All TypeBox types extend the base type TSchema; it is best practice to constrain generic arguments to this type. The following creates a generic Vector type.
|
|
696
700
|
|
|
697
701
|
```typescript
|
|
698
702
|
import { Type, Static, TSchema } from '@sinclair/typebox'
|
|
699
703
|
|
|
700
704
|
const Vector = <T extends TSchema>(t: T) => Type.Object({ x: t, y: t, z: t })
|
|
701
705
|
|
|
702
|
-
const NumberVector = Vector(Type.Number())
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
type NumberVector = Static<typeof NumberVector>
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
706
|
+
const NumberVector = Vector(Type.Number()) // const NumberVector = {
|
|
707
|
+
// type: 'object',
|
|
708
|
+
// required: ['x', 'y', 'z'],
|
|
709
|
+
// properties: {
|
|
710
|
+
// x: { type: 'number' },
|
|
711
|
+
// y: { type: 'number' },
|
|
712
|
+
// z: { type: 'number' }
|
|
713
|
+
// }
|
|
714
|
+
// }
|
|
715
|
+
|
|
716
|
+
type NumberVector = Static<typeof NumberVector> // type NumberVector = {
|
|
717
|
+
// x: number,
|
|
718
|
+
// y: number,
|
|
719
|
+
// z: number
|
|
720
|
+
// }
|
|
717
721
|
```
|
|
718
722
|
|
|
719
|
-
Generic types can be used to create aliases for more complex types. The following creates a
|
|
723
|
+
Generic types can be used to create aliases for more complex types. The following creates a Nullable generic type.
|
|
720
724
|
|
|
721
725
|
```typescript
|
|
722
726
|
const Nullable = <T extends TSchema>(schema: T) => Type.Union([schema, Type.Null()])
|
|
@@ -735,55 +739,55 @@ type T = Static<typeof T> // type T = string | null
|
|
|
735
739
|
|
|
736
740
|
### Reference Types
|
|
737
741
|
|
|
738
|
-
Reference types are supported with
|
|
742
|
+
Reference types are supported with Ref.
|
|
739
743
|
|
|
740
744
|
```typescript
|
|
741
|
-
const T = Type.String({ $id: 'T' })
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
+
const T = Type.String({ $id: 'T' }) // const T = {
|
|
746
|
+
// $id: 'T',
|
|
747
|
+
// type: 'string'
|
|
748
|
+
// }
|
|
745
749
|
|
|
746
|
-
const R = Type.Ref<typeof T>('T')
|
|
747
|
-
|
|
748
|
-
|
|
750
|
+
const R = Type.Ref<typeof T>('T') // const R = {
|
|
751
|
+
// $ref: 'T'
|
|
752
|
+
// }
|
|
749
753
|
|
|
750
|
-
type R = Static<typeof R>
|
|
754
|
+
type R = Static<typeof R> // type R = string
|
|
751
755
|
```
|
|
752
756
|
|
|
753
757
|
<a name='types-recursive'></a>
|
|
754
758
|
|
|
755
759
|
### Recursive Types
|
|
756
760
|
|
|
757
|
-
|
|
761
|
+
TypeBox supports singular recursive data structures. Recursive type inference is also supported. The following creates a recursive Node structure.
|
|
758
762
|
|
|
759
763
|
```typescript
|
|
760
|
-
const Node = Type.Recursive(This => Type.Object({
|
|
761
|
-
id: Type.String(),
|
|
762
|
-
nodes: Type.Array(This)
|
|
763
|
-
}), { $id: 'Node' })
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
type Node = Static<typeof Node>
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
764
|
+
const Node = Type.Recursive(This => Type.Object({ // const Node = {
|
|
765
|
+
id: Type.String(), // $id: 'Node',
|
|
766
|
+
nodes: Type.Array(This) // type: 'object',
|
|
767
|
+
}), { $id: 'Node' }) // properties: {
|
|
768
|
+
// id: {
|
|
769
|
+
// type: 'string'
|
|
770
|
+
// },
|
|
771
|
+
// nodes: {
|
|
772
|
+
// type: 'array',
|
|
773
|
+
// items: {
|
|
774
|
+
// $ref: 'Node'
|
|
775
|
+
// }
|
|
776
|
+
// }
|
|
777
|
+
// },
|
|
778
|
+
// required: [
|
|
779
|
+
// 'id',
|
|
780
|
+
// 'nodes'
|
|
781
|
+
// ]
|
|
782
|
+
// }
|
|
783
|
+
|
|
784
|
+
type Node = Static<typeof Node> // type Node = {
|
|
785
|
+
// id: string
|
|
786
|
+
// nodes: Node[]
|
|
787
|
+
// }
|
|
784
788
|
|
|
785
789
|
function test(node: Node) {
|
|
786
|
-
const id = node.nodes[0].nodes[0].id
|
|
790
|
+
const id = node.nodes[0].nodes[0].id // id is string
|
|
787
791
|
}
|
|
788
792
|
```
|
|
789
793
|
|
|
@@ -791,7 +795,7 @@ function test(node: Node) {
|
|
|
791
795
|
|
|
792
796
|
### Conditional Types
|
|
793
797
|
|
|
794
|
-
TypeBox supports conditional types with
|
|
798
|
+
TypeBox supports conditional types with Extends. This type performs a structural assignability check for the first two arguments and returns either of the second two arguments based on the result. This type is modelled after TypeScript conditional types. The Exclude and Extract conditional types are also supported.
|
|
795
799
|
|
|
796
800
|
```typescript
|
|
797
801
|
// TypeScript
|
|
@@ -834,143 +838,153 @@ const T2 = Type.Exclude( // const T2: TUnion<[
|
|
|
834
838
|
// }
|
|
835
839
|
```
|
|
836
840
|
|
|
837
|
-
<a name='types-
|
|
841
|
+
<a name='types-templateliteral'></a>
|
|
838
842
|
|
|
839
843
|
### Template Literal Types
|
|
840
844
|
|
|
841
|
-
TypeBox supports template literal types with
|
|
845
|
+
TypeBox supports template literal types with TemplateLiteral. This type can be created using a string syntax that is partially modelled on the TypeScript template literal syntax. This type can also be constructed by passing an array of Union and Literal types in sequence. The following example shows the string syntax.
|
|
842
846
|
|
|
843
847
|
```typescript
|
|
844
848
|
// TypeScript
|
|
845
849
|
|
|
846
|
-
type T = `option${'A'|'B'|'C'}`
|
|
850
|
+
type T = `option${'A'|'B'|'C'}` // type T = 'optionA' | 'optionB' | 'optionC'
|
|
847
851
|
|
|
848
|
-
type R = Record<T, string>
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
852
|
+
type R = Record<T, string> // type R = {
|
|
853
|
+
// optionA: string
|
|
854
|
+
// optionB: string
|
|
855
|
+
// optionC: string
|
|
856
|
+
// }
|
|
853
857
|
|
|
854
858
|
// TypeBox
|
|
855
859
|
|
|
856
|
-
const T = Type.TemplateLiteral('option${A|B|C}')
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
const R = Type.Record(T, Type.String())
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
860
|
+
const T = Type.TemplateLiteral('option${A|B|C}') // const T = {
|
|
861
|
+
// pattern: '^option(A|B|C)$',
|
|
862
|
+
// type: 'string'
|
|
863
|
+
// }
|
|
864
|
+
|
|
865
|
+
const R = Type.Record(T, Type.String()) // const R = {
|
|
866
|
+
// type: 'object',
|
|
867
|
+
// required: ['optionA', 'optionB'],
|
|
868
|
+
// properties: {
|
|
869
|
+
// optionA: {
|
|
870
|
+
// type: 'string'
|
|
871
|
+
// },
|
|
872
|
+
// optionB: {
|
|
873
|
+
// type: 'string'
|
|
874
|
+
// }
|
|
875
|
+
// optionC: {
|
|
876
|
+
// type: 'string'
|
|
877
|
+
// }
|
|
878
|
+
// }
|
|
879
|
+
// }
|
|
876
880
|
```
|
|
877
881
|
|
|
878
882
|
<a name='types-indexed'></a>
|
|
879
883
|
|
|
880
884
|
### Indexed Access Types
|
|
881
885
|
|
|
882
|
-
TypeBox supports
|
|
886
|
+
TypeBox supports Indexed Access Types with the Index type. This type offers a uniform way to access interior property and array element types without having to extract them from the underlying schema representation. This type is supported for Object, Array, Tuple, Union and Intersect types.
|
|
883
887
|
|
|
884
888
|
```typescript
|
|
885
|
-
const T = Type.Object({
|
|
886
|
-
x: Type.Number(),
|
|
887
|
-
y: Type.String(),
|
|
888
|
-
z: Type.Boolean()
|
|
889
|
-
})
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
const A = Type.Index(T, ['x'])
|
|
896
|
-
|
|
897
|
-
const B = Type.Index(T, ['x', 'y'])
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
const C = Type.Index(T, Type.KeyOf(T))
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
889
|
+
const T = Type.Object({ // const T = {
|
|
890
|
+
x: Type.Number(), // type: 'object',
|
|
891
|
+
y: Type.String(), // required: ['x', 'y', 'z'],
|
|
892
|
+
z: Type.Boolean() // properties: {
|
|
893
|
+
}) // x: { type: 'number' },
|
|
894
|
+
// y: { type: 'string' },
|
|
895
|
+
// z: { type: 'string' }
|
|
896
|
+
// }
|
|
897
|
+
// }
|
|
898
|
+
|
|
899
|
+
const A = Type.Index(T, ['x']) // const A = { type: 'number' }
|
|
900
|
+
|
|
901
|
+
const B = Type.Index(T, ['x', 'y']) // const B = {
|
|
902
|
+
// anyOf: [
|
|
903
|
+
// { type: 'number' },
|
|
904
|
+
// { type: 'string' }
|
|
905
|
+
// ]
|
|
906
|
+
// }
|
|
907
|
+
|
|
908
|
+
const C = Type.Index(T, Type.KeyOf(T)) // const C = {
|
|
909
|
+
// anyOf: [
|
|
910
|
+
// { type: 'number' },
|
|
911
|
+
// { type: 'string' },
|
|
912
|
+
// { type: 'boolean' }
|
|
913
|
+
// ]
|
|
914
|
+
// }
|
|
911
915
|
```
|
|
912
916
|
|
|
913
|
-
<a name='types-
|
|
917
|
+
<a name='types-rest'></a>
|
|
914
918
|
|
|
915
|
-
###
|
|
919
|
+
### Rest Types
|
|
916
920
|
|
|
917
|
-
TypeBox
|
|
921
|
+
TypeBox provides the Rest type to uniformly extract the variadic tuple passed to Intersect, Union and Tuple types. This type can be useful to remap variadic types into different forms. The following uses the Rest type to remap a Tuple into a Union.
|
|
918
922
|
|
|
919
923
|
```typescript
|
|
920
|
-
const T = Type.
|
|
921
|
-
|
|
924
|
+
const T = Type.Tuple([ // const T = {
|
|
925
|
+
Type.String(), // type: 'array',
|
|
926
|
+
Type.Number() // items: [
|
|
927
|
+
]) // { type: 'string' },
|
|
928
|
+
// { type: 'number' }
|
|
929
|
+
// ],
|
|
930
|
+
// additionalItems: false,
|
|
931
|
+
// minItems: 2,
|
|
932
|
+
// maxItems: 2,
|
|
922
933
|
// }
|
|
923
934
|
|
|
924
|
-
|
|
925
|
-
//
|
|
926
|
-
//
|
|
935
|
+
const R = Type.Rest(T) // const R = [
|
|
936
|
+
// { type: 'string' },
|
|
937
|
+
// { type: 'number' }
|
|
938
|
+
// ]
|
|
939
|
+
|
|
940
|
+
const U = Type.Union(R) // const U = {
|
|
941
|
+
// anyOf: [
|
|
942
|
+
// { type: 'string' },
|
|
943
|
+
// { type: 'number' }
|
|
944
|
+
// ]
|
|
945
|
+
// }
|
|
927
946
|
```
|
|
928
|
-
Type negation can be useful for certain forms of type narrowing. For example, consider a type that represents a `number` but not the numbers `1, 2, 3`. The example below shows an imaginary TypeScript syntax to express such a type followed by the TypeBox representation.
|
|
929
947
|
|
|
930
|
-
|
|
931
|
-
// TypeScript
|
|
948
|
+
<a name='types-transform'></a>
|
|
932
949
|
|
|
933
|
-
|
|
950
|
+
### Transform Types
|
|
934
951
|
|
|
935
|
-
|
|
952
|
+
TypeBox supports bi-directional value encoding and decoding with Transform types. These types are designed to operate specifically with the Value and TypeCompiler Encode and Decode functions. Transform types can be used to convert Json encoded values into constructs more natural to JavaScript. The following creates a Transform type to convert between Date and number using the Value module.
|
|
953
|
+
|
|
954
|
+
```typescript
|
|
955
|
+
import { Value } from '@sinclair/typebox/value'
|
|
956
|
+
|
|
957
|
+
const T = Type.Transform(Type.Number())
|
|
958
|
+
.Decode(value => new Date(value)) // required: number to Date
|
|
959
|
+
.Encode(value => value.getTime()) // required: Date to number
|
|
936
960
|
|
|
937
|
-
const
|
|
938
|
-
|
|
939
|
-
Type.Not(Type.Union([ // { type: "number" },
|
|
940
|
-
Type.Literal(1), // {
|
|
941
|
-
Type.Literal(2), // not: {
|
|
942
|
-
Type.Literal(3) // anyOf: [
|
|
943
|
-
])) // { const: 1, type: "number" },
|
|
944
|
-
]) // { const: 2, type: "number" },
|
|
945
|
-
// { const: 3, type: "number" }
|
|
946
|
-
// ]
|
|
947
|
-
// }
|
|
948
|
-
// }
|
|
949
|
-
// ]
|
|
950
|
-
// }
|
|
951
|
-
|
|
952
|
-
type T = Static<typeof T> // type T = number
|
|
961
|
+
const decoded = Value.Decode(T, 0) // const decoded = Date(1970-01-01T00:00:00.000Z)
|
|
962
|
+
const encoded = Value.Encode(T, decoded) // const encoded = 0
|
|
953
963
|
```
|
|
954
|
-
|
|
964
|
+
Use the StaticEncode or StaticDecode types to infer a Transform type.
|
|
955
965
|
```typescript
|
|
956
|
-
|
|
966
|
+
import { Static, StaticDecode, StaticEncode } from '@sinclair/typebox'
|
|
957
967
|
|
|
958
|
-
const
|
|
968
|
+
const T = Type.Transform(Type.Array(Type.Number(), { uniqueItems: true }))
|
|
969
|
+
.Decode(value => new Set(value))
|
|
970
|
+
.Encode(value => [...value])
|
|
971
|
+
|
|
972
|
+
type D = StaticDecode<typeof T> // type D = Set<number>
|
|
973
|
+
type E = StaticEncode<typeof T> // type E = Array<number>
|
|
974
|
+
type T = Static<typeof T> // type T = Array<number>
|
|
959
975
|
```
|
|
960
976
|
|
|
961
977
|
<a name='types-intrinsic'></a>
|
|
962
978
|
|
|
963
|
-
### Intrinsic
|
|
979
|
+
### Intrinsic Types
|
|
964
980
|
|
|
965
|
-
TypeBox supports TypeScript
|
|
981
|
+
TypeBox supports the TypeScript Intrinsic String Manipulation types Uppercase, Lowercase, Capitalize and Uncapitalize. These types can be used to remap String Literal, TemplateLiteral and Union types. The following shows general usage.
|
|
966
982
|
|
|
967
983
|
```typescript
|
|
968
984
|
// TypeScript
|
|
969
985
|
|
|
970
986
|
type A = Capitalize<'hello'> // type A = 'Hello'
|
|
971
|
-
|
|
972
987
|
type B = Capitalize<'hello' | 'world'> // type C = 'Hello' | 'World'
|
|
973
|
-
|
|
974
988
|
type C = Capitalize<`hello${1|2|3}`> // type B = 'Hello1' | 'Hello2' | 'Hello3'
|
|
975
989
|
|
|
976
990
|
// TypeBox
|
|
@@ -992,94 +1006,47 @@ const C = Type.Capitalize( // const C: TTemplateLiteral
|
|
|
992
1006
|
// ]>
|
|
993
1007
|
```
|
|
994
1008
|
|
|
995
|
-
<a name='types-rest'></a>
|
|
996
|
-
|
|
997
|
-
### Rest Types
|
|
998
|
-
|
|
999
|
-
Rest parameters are supported with `Rest`. This function is used to extract interior type elements from tuples which enables them to compose with the JavaScript spread operator `...`. This type can be used for tuple concatenation as well function parameter assignment.
|
|
1000
|
-
|
|
1001
|
-
```typescript
|
|
1002
|
-
// TypeScript
|
|
1003
|
-
|
|
1004
|
-
type T = [number, number] // type T = [number, number]
|
|
1005
|
-
|
|
1006
|
-
type C = [...T, number] // type C = [number, number, number]
|
|
1007
|
-
|
|
1008
|
-
type F = (...param: C) => void // type F = (
|
|
1009
|
-
// param0: number,
|
|
1010
|
-
// param1: number,
|
|
1011
|
-
// param2: number
|
|
1012
|
-
// ) => void
|
|
1013
|
-
|
|
1014
|
-
// TypeBox
|
|
1015
|
-
|
|
1016
|
-
const T = Type.Tuple([ // const T: TTuple<[
|
|
1017
|
-
Type.Number(), // TNumber,
|
|
1018
|
-
Type.Number() // TNumber
|
|
1019
|
-
]) // ]>
|
|
1020
|
-
|
|
1021
|
-
const C = Type.Tuple([ // const C: TTuple<[
|
|
1022
|
-
...Type.Rest(T), // TNumber,
|
|
1023
|
-
Type.Number() // TNumber,
|
|
1024
|
-
]) // TNumber
|
|
1025
|
-
// ]>
|
|
1026
|
-
|
|
1027
|
-
const F = Type.Function(Type.Rest(C), Type.Void()) // const F: TFunction<[
|
|
1028
|
-
// TNumber,
|
|
1029
|
-
// TNumber,
|
|
1030
|
-
// TNumber
|
|
1031
|
-
// ], TVoid>
|
|
1032
|
-
```
|
|
1033
1009
|
<a name='types-unsafe'></a>
|
|
1034
1010
|
|
|
1035
1011
|
### Unsafe Types
|
|
1036
1012
|
|
|
1037
|
-
TypeBox supports
|
|
1013
|
+
TypeBox supports user defined types with Unsafe. This type allows you to specify both schema representation and inference type. The following creates an Unsafe type with a number schema that infers as string.
|
|
1038
1014
|
|
|
1039
1015
|
```typescript
|
|
1040
|
-
const T = Type.Unsafe<string>({ type: 'number' })
|
|
1041
|
-
|
|
1042
|
-
|
|
1016
|
+
const T = Type.Unsafe<string>({ type: 'number' }) // const T = {
|
|
1017
|
+
// type: 'number'
|
|
1018
|
+
// }
|
|
1043
1019
|
|
|
1044
|
-
type T = Static<typeof T>
|
|
1020
|
+
type T = Static<typeof T> // type T = string ?
|
|
1045
1021
|
```
|
|
1046
|
-
|
|
1047
|
-
This type can be useful to create various extended schematics, such as those used by OpenAPI.
|
|
1048
|
-
|
|
1022
|
+
The Unsafe type are often used to create schematics for specifications like OpenAPI
|
|
1049
1023
|
```typescript
|
|
1050
|
-
import { Type, Static, TSchema } from '@sinclair/typebox'
|
|
1051
|
-
|
|
1052
|
-
// Nullable<T>
|
|
1053
1024
|
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
const T = Nullable(Type.String()) // const T = {
|
|
1059
|
-
// type: 'string',
|
|
1060
|
-
// nullable: true
|
|
1061
|
-
// }
|
|
1062
|
-
|
|
1063
|
-
type T = Static<typeof T> // type T = string | null
|
|
1025
|
+
const Nullable = <T extends TSchema>(schema: T) => Type.Unsafe<Static<T> | null>({
|
|
1026
|
+
...schema, nullable: true
|
|
1027
|
+
})
|
|
1064
1028
|
|
|
1065
|
-
//
|
|
1029
|
+
const T = Nullable(Type.String()) // const T = {
|
|
1030
|
+
// type: 'string',
|
|
1031
|
+
// nullable: true
|
|
1032
|
+
// }
|
|
1066
1033
|
|
|
1067
|
-
|
|
1068
|
-
return Type.Unsafe<T[number]>({ type: 'string', enum: values })
|
|
1069
|
-
}
|
|
1034
|
+
type T = Static<typeof T> // type T = string | null
|
|
1070
1035
|
|
|
1071
|
-
const
|
|
1072
|
-
|
|
1073
|
-
|
|
1036
|
+
const StringEnum = <T extends string[]>(values: [...T]) => Type.Unsafe<T[number]>({
|
|
1037
|
+
type: 'string', enum: values
|
|
1038
|
+
})
|
|
1039
|
+
const S = StringEnum(['A', 'B', 'C']) // const S = {
|
|
1040
|
+
// enum: ['A', 'B', 'C']
|
|
1041
|
+
// }
|
|
1074
1042
|
|
|
1075
|
-
type
|
|
1043
|
+
type S = Static<typeof T> // type S = 'A' | 'B' | 'C'
|
|
1076
1044
|
```
|
|
1077
|
-
|
|
1078
1045
|
<a name='types-guards'></a>
|
|
1079
1046
|
|
|
1080
1047
|
### Type Guards
|
|
1081
1048
|
|
|
1082
|
-
TypeBox provides a TypeGuard module to
|
|
1049
|
+
TypeBox provides a TypeGuard module to check JavaScript values are valid TypeBox types. The following checks the value T is TString.
|
|
1083
1050
|
|
|
1084
1051
|
```typescript
|
|
1085
1052
|
import { Type, Kind, TypeGuard } from '@sinclair/typebox'
|
|
@@ -1096,36 +1063,36 @@ if(TypeGuard.TString(T)) {
|
|
|
1096
1063
|
|
|
1097
1064
|
### Strict
|
|
1098
1065
|
|
|
1099
|
-
TypeBox types contain various symbol properties that are used for reflection, composition and compilation. These properties are not strictly valid
|
|
1066
|
+
TypeBox types contain various symbol properties that are used for reflection, composition and compilation. These properties are not strictly valid Json Schema; so in some cases it may be desirable to omit them. TypeBox provides a `Strict` function that will omit these properties if necessary.
|
|
1100
1067
|
|
|
1101
1068
|
```typescript
|
|
1102
|
-
const T = Type.Object({
|
|
1103
|
-
name: Type.Optional(Type.String())
|
|
1104
|
-
})
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
const U = Type.Strict(T)
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1069
|
+
const T = Type.Object({ // const T = {
|
|
1070
|
+
name: Type.Optional(Type.String()) // [Kind]: 'Object',
|
|
1071
|
+
}) // type: 'object',
|
|
1072
|
+
// properties: {
|
|
1073
|
+
// name: {
|
|
1074
|
+
// type: 'string',
|
|
1075
|
+
// [Kind]: 'String',
|
|
1076
|
+
// [Optional]: 'Optional'
|
|
1077
|
+
// }
|
|
1078
|
+
// }
|
|
1079
|
+
// }
|
|
1080
|
+
|
|
1081
|
+
const U = Type.Strict(T) // const U = {
|
|
1082
|
+
// type: 'object',
|
|
1083
|
+
// properties: {
|
|
1084
|
+
// name: {
|
|
1085
|
+
// type: 'string'
|
|
1086
|
+
// }
|
|
1087
|
+
// }
|
|
1088
|
+
// }
|
|
1122
1089
|
```
|
|
1123
1090
|
|
|
1124
1091
|
<a name='values'></a>
|
|
1125
1092
|
|
|
1126
1093
|
## Values
|
|
1127
1094
|
|
|
1128
|
-
TypeBox provides an optional utility module that can be used to perform
|
|
1095
|
+
TypeBox provides an optional utility module that can be used to perform structural operations on JavaScript values. This module includes functionality to create, check and cast values from types as well as check equality, clone, diff and patch JavaScript values. This module is provided via optional import.
|
|
1129
1096
|
|
|
1130
1097
|
```typescript
|
|
1131
1098
|
import { Value } from '@sinclair/typebox/value'
|
|
@@ -1140,7 +1107,7 @@ Use the Create function to create a value from a type. TypeBox will use default
|
|
|
1140
1107
|
```typescript
|
|
1141
1108
|
const T = Type.Object({ x: Type.Number(), y: Type.Number({ default: 42 }) })
|
|
1142
1109
|
|
|
1143
|
-
const A = Value.Create(T)
|
|
1110
|
+
const A = Value.Create(T) // const A = { x: 0, y: 42 }
|
|
1144
1111
|
```
|
|
1145
1112
|
|
|
1146
1113
|
<a name='values-clone'></a>
|
|
@@ -1150,7 +1117,7 @@ const A = Value.Create(T) // const A = { x: 0, y: 42
|
|
|
1150
1117
|
Use the Clone function to deeply clone a value
|
|
1151
1118
|
|
|
1152
1119
|
```typescript
|
|
1153
|
-
const A = Value.Clone({ x: 1, y: 2, z: 3 })
|
|
1120
|
+
const A = Value.Clone({ x: 1, y: 2, z: 3 }) // const A = { x: 1, y: 2, z: 3 }
|
|
1154
1121
|
```
|
|
1155
1122
|
|
|
1156
1123
|
<a name='values-check'></a>
|
|
@@ -1162,14 +1129,14 @@ Use the Check function to type check a value
|
|
|
1162
1129
|
```typescript
|
|
1163
1130
|
const T = Type.Object({ x: Type.Number() })
|
|
1164
1131
|
|
|
1165
|
-
const R = Value.Check(T, { x: 1 })
|
|
1132
|
+
const R = Value.Check(T, { x: 1 }) // const R = true
|
|
1166
1133
|
```
|
|
1167
1134
|
|
|
1168
1135
|
<a name='values-convert'></a>
|
|
1169
1136
|
|
|
1170
1137
|
### Convert
|
|
1171
1138
|
|
|
1172
|
-
Use the Convert function to convert a value into its target type if a reasonable conversion is possible. This function may return an invalid value and should be checked before use.
|
|
1139
|
+
Use the Convert function to convert a value into its target type if a reasonable conversion is possible. This function may return an invalid value and should be checked before use. Its return type is `unknown`.
|
|
1173
1140
|
|
|
1174
1141
|
```typescript
|
|
1175
1142
|
const T = Type.Object({ x: Type.Number() })
|
|
@@ -1188,11 +1155,33 @@ Use the Cast function to cast a value into a type. The cast function will retain
|
|
|
1188
1155
|
```typescript
|
|
1189
1156
|
const T = Type.Object({ x: Type.Number(), y: Type.Number() }, { additionalProperties: false })
|
|
1190
1157
|
|
|
1191
|
-
const X = Value.Cast(T, null)
|
|
1158
|
+
const X = Value.Cast(T, null) // const X = { x: 0, y: 0 }
|
|
1159
|
+
|
|
1160
|
+
const Y = Value.Cast(T, { x: 1 }) // const Y = { x: 1, y: 0 }
|
|
1161
|
+
|
|
1162
|
+
const Z = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const Z = { x: 1, y: 2 }
|
|
1163
|
+
```
|
|
1164
|
+
|
|
1165
|
+
<a name='values-decode'></a>
|
|
1166
|
+
|
|
1167
|
+
### Decode
|
|
1168
|
+
|
|
1169
|
+
Use the Decode function to decode a value from a type or throw if the value is invalid. The return value will infer as the given type. This function will run Transform decode functions if available.
|
|
1170
|
+
|
|
1171
|
+
```typescript
|
|
1172
|
+
const A = Type.Decode(Type.String(), 'hello') // const A = 'hello'
|
|
1173
|
+
|
|
1174
|
+
const B = Type.Decode(Type.String(), 42) // throw
|
|
1175
|
+
```
|
|
1176
|
+
<a name='values-decode'></a>
|
|
1192
1177
|
|
|
1193
|
-
|
|
1178
|
+
### Encode
|
|
1194
1179
|
|
|
1195
|
-
|
|
1180
|
+
Use the Encode function to encode a value from a type or throw if the value is invalid. The return value will infer as the given type. This function will run Transform encode functions if available. When encoding with types without Transforms, this function is equivalent to Decode.
|
|
1181
|
+
```typescript
|
|
1182
|
+
const A = Type.Encode(Type.String(), 'hello') // const A = 'hello'
|
|
1183
|
+
|
|
1184
|
+
const B = Type.Encode(Type.String(), 42) // throw
|
|
1196
1185
|
```
|
|
1197
1186
|
|
|
1198
1187
|
<a name='values-equal'></a>
|
|
@@ -1202,7 +1191,7 @@ const Z = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const Z = { x: 1, y: 2 }
|
|
|
1202
1191
|
Use the Equal function to deeply check for value equality.
|
|
1203
1192
|
|
|
1204
1193
|
```typescript
|
|
1205
|
-
const R = Value.Equal(
|
|
1194
|
+
const R = Value.Equal( // const R = true
|
|
1206
1195
|
{ x: 1, y: 2, z: 3 },
|
|
1207
1196
|
{ x: 1, y: 2, z: 3 }
|
|
1208
1197
|
)
|
|
@@ -1239,19 +1228,19 @@ const E = Value.Diff( // const E = [
|
|
|
1239
1228
|
|
|
1240
1229
|
### Patch
|
|
1241
1230
|
|
|
1242
|
-
Use the Patch function to apply edits
|
|
1231
|
+
Use the Patch function to apply Diff edits
|
|
1243
1232
|
|
|
1244
1233
|
```typescript
|
|
1245
1234
|
const A = { x: 1, y: 2 }
|
|
1246
1235
|
|
|
1247
1236
|
const B = { x: 3 }
|
|
1248
1237
|
|
|
1249
|
-
const E = Value.Diff(A, B)
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1238
|
+
const E = Value.Diff(A, B) // const E = [
|
|
1239
|
+
// { type: 'update', path: '/x', value: 3 },
|
|
1240
|
+
// { type: 'delete', path: '/y' }
|
|
1241
|
+
// ]
|
|
1253
1242
|
|
|
1254
|
-
const C = Value.Patch<typeof B>(A, E)
|
|
1243
|
+
const C = Value.Patch<typeof B>(A, E) // const C = { x: 3 }
|
|
1255
1244
|
```
|
|
1256
1245
|
|
|
1257
1246
|
<a name='values-errors'></a>
|
|
@@ -1263,17 +1252,17 @@ Use the Errors function enumerate validation errors.
|
|
|
1263
1252
|
```typescript
|
|
1264
1253
|
const T = Type.Object({ x: Type.Number(), y: Type.Number() })
|
|
1265
1254
|
|
|
1266
|
-
const R = [...Value.Errors(T, { x: '42' })]
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1255
|
+
const R = [...Value.Errors(T, { x: '42' })] // const R = [{
|
|
1256
|
+
// schema: { type: 'number' },
|
|
1257
|
+
// path: '/x',
|
|
1258
|
+
// value: '42',
|
|
1259
|
+
// message: 'Expected number'
|
|
1260
|
+
// }, {
|
|
1261
|
+
// schema: { type: 'number' },
|
|
1262
|
+
// path: '/y',
|
|
1263
|
+
// value: undefined,
|
|
1264
|
+
// message: 'Expected number'
|
|
1265
|
+
// }]
|
|
1277
1266
|
```
|
|
1278
1267
|
|
|
1279
1268
|
<a name='values-mutate'></a>
|
|
@@ -1283,47 +1272,87 @@ const R = [...Value.Errors(T, { x: '42' })] // const R = [{
|
|
|
1283
1272
|
Use the Mutate function to perform a deep mutable value assignment while retaining internal references.
|
|
1284
1273
|
|
|
1285
1274
|
```typescript
|
|
1286
|
-
const Y = { z: 1 }
|
|
1275
|
+
const Y = { z: 1 } // const Y = { z: 1 }
|
|
1287
1276
|
|
|
1288
|
-
const X = { y: Y }
|
|
1277
|
+
const X = { y: Y } // const X = { y: { z: 1 } }
|
|
1289
1278
|
|
|
1290
|
-
const A = { x: X }
|
|
1279
|
+
const A = { x: X } // const A = { x: { y: { z: 1 } } }
|
|
1291
1280
|
|
|
1292
1281
|
|
|
1293
|
-
Value.Mutate(A, { x: { y: { z: 2 } } })
|
|
1282
|
+
Value.Mutate(A, { x: { y: { z: 2 } } }) // const A' = { x: { y: { z: 2 } } }
|
|
1294
1283
|
|
|
1295
|
-
const R0 = A.x.y.z === 2
|
|
1284
|
+
const R0 = A.x.y.z === 2 // const R0 = true
|
|
1296
1285
|
|
|
1297
|
-
const R1 = A.x.y === Y
|
|
1286
|
+
const R1 = A.x.y === Y // const R1 = true
|
|
1298
1287
|
|
|
1299
|
-
const R2 = A.x === X
|
|
1288
|
+
const R2 = A.x === X // const R2 = true
|
|
1300
1289
|
```
|
|
1301
1290
|
|
|
1302
1291
|
<a name='values-pointer'></a>
|
|
1303
1292
|
|
|
1304
1293
|
### Pointer
|
|
1305
1294
|
|
|
1306
|
-
Use ValuePointer to perform mutable updates on existing values using [RFC6901](https://www.rfc-editor.org/rfc/rfc6901)
|
|
1295
|
+
Use ValuePointer to perform mutable updates on existing values using [RFC6901](https://www.rfc-editor.org/rfc/rfc6901) Json Pointers.
|
|
1307
1296
|
|
|
1308
1297
|
```typescript
|
|
1309
1298
|
import { ValuePointer } from '@sinclair/typebox/value'
|
|
1310
1299
|
|
|
1311
1300
|
const A = { x: 0, y: 0, z: 0 }
|
|
1312
1301
|
|
|
1313
|
-
ValuePointer.Set(A, '/x', 1)
|
|
1302
|
+
ValuePointer.Set(A, '/x', 1) // const A' = { x: 1, y: 0, z: 0 }
|
|
1314
1303
|
|
|
1315
|
-
ValuePointer.Set(A, '/y', 1)
|
|
1304
|
+
ValuePointer.Set(A, '/y', 1) // const A' = { x: 1, y: 1, z: 0 }
|
|
1316
1305
|
|
|
1317
|
-
ValuePointer.Set(A, '/z', 1)
|
|
1306
|
+
ValuePointer.Set(A, '/z', 1) // const A' = { x: 1, y: 1, z: 1 }
|
|
1307
|
+
```
|
|
1308
|
+
|
|
1309
|
+
<a name='typeregistry'></a>
|
|
1310
|
+
|
|
1311
|
+
## TypeRegistry
|
|
1312
|
+
|
|
1313
|
+
The TypeBox type system can be extended with additional types and formats using the TypeRegistry and FormatRegistry modules. These modules integrate deeply with TypeBox's internal type checking infrastructure and can be used to create application specific types, or express schematics for alternative schema specifications.
|
|
1314
|
+
|
|
1315
|
+
<a name='typeregistry-type'></a>
|
|
1316
|
+
|
|
1317
|
+
### TypeRegistry
|
|
1318
|
+
|
|
1319
|
+
Use the TypeRegistry to register a new type. The Kind must match the registered type name.
|
|
1320
|
+
|
|
1321
|
+
```typescript
|
|
1322
|
+
import { TypeRegistry, Kind } from '@sinclair/typebox'
|
|
1323
|
+
|
|
1324
|
+
TypeRegistry.Set('Foo', (schema, value) => value === 'foo')
|
|
1325
|
+
|
|
1326
|
+
const A = Value.Check({ [Kind]: 'Foo' }, 'foo') // const A = true
|
|
1327
|
+
|
|
1328
|
+
const B = Value.Check({ [Kind]: 'Foo' }, 'bar') // const B = false
|
|
1329
|
+
```
|
|
1330
|
+
|
|
1331
|
+
<a name='typeregistry-format'></a>
|
|
1332
|
+
|
|
1333
|
+
### FormatRegistry
|
|
1334
|
+
|
|
1335
|
+
Use the FormatRegistry to register a string format.
|
|
1336
|
+
|
|
1337
|
+
```typescript
|
|
1338
|
+
import { FormatRegistry } from '@sinclair/typebox'
|
|
1339
|
+
|
|
1340
|
+
FormatRegistry.Set('foo', (value) => value === 'foo')
|
|
1341
|
+
|
|
1342
|
+
const T = Type.String({ format: 'foo' })
|
|
1343
|
+
|
|
1344
|
+
const A = Value.Check(T, 'foo') // const A = true
|
|
1345
|
+
|
|
1346
|
+
const B = Value.Check(T, 'bar') // const B = false
|
|
1318
1347
|
```
|
|
1319
1348
|
|
|
1320
1349
|
<a name='typecheck'></a>
|
|
1321
1350
|
|
|
1322
1351
|
## TypeCheck
|
|
1323
1352
|
|
|
1324
|
-
TypeBox types target
|
|
1353
|
+
TypeBox types target Json Schema Draft 7 and are compatible with any validator that supports this specification. TypeBox also provides a built in type checking compiler designed specifically for TypeBox types that offers high performance compilation and value assertion.
|
|
1325
1354
|
|
|
1326
|
-
The following sections detail using Ajv and TypeBox
|
|
1355
|
+
The following sections detail using Ajv and the TypeBox compiler infrastructure.
|
|
1327
1356
|
|
|
1328
1357
|
<a name='typecheck-ajv'></a>
|
|
1329
1358
|
|
|
@@ -1357,20 +1386,20 @@ const ajv = addFormats(new Ajv({}), [
|
|
|
1357
1386
|
'regex'
|
|
1358
1387
|
])
|
|
1359
1388
|
|
|
1360
|
-
const
|
|
1389
|
+
const validate = ajv.compile(Type.Object({
|
|
1361
1390
|
x: Type.Number(),
|
|
1362
1391
|
y: Type.Number(),
|
|
1363
1392
|
z: Type.Number()
|
|
1364
1393
|
}))
|
|
1365
1394
|
|
|
1366
|
-
const R =
|
|
1395
|
+
const R = validate({ x: 1, y: 2, z: 3 }) // const R = true
|
|
1367
1396
|
```
|
|
1368
1397
|
|
|
1369
1398
|
<a name='typecheck-typecompiler'></a>
|
|
1370
1399
|
|
|
1371
1400
|
### TypeCompiler
|
|
1372
1401
|
|
|
1373
|
-
The TypeBox TypeCompiler is a high performance JIT compiler that transforms TypeBox types into optimized JavaScript validation routines. The compiler is tuned for fast compilation as well as fast
|
|
1402
|
+
The TypeBox TypeCompiler is a high performance JIT compiler that transforms TypeBox types into optimized JavaScript validation routines. The compiler is tuned for fast compilation as well as fast assertion. It is built to serve as a validation backend that can be integrated into larger applications and frameworks; but can also be used as a general purpose validator.
|
|
1374
1403
|
|
|
1375
1404
|
The TypeCompiler is provided as an optional import.
|
|
1376
1405
|
|
|
@@ -1378,157 +1407,209 @@ The TypeCompiler is provided as an optional import.
|
|
|
1378
1407
|
import { TypeCompiler } from '@sinclair/typebox/compiler'
|
|
1379
1408
|
```
|
|
1380
1409
|
|
|
1381
|
-
Use the
|
|
1410
|
+
Use the Compile function to JIT compile a type. Note that compilation is generally an expensive operation and should only be performed once per type during application start up. TypeBox does not cache previously compiled types, and applications are expected to hold references to each compiled type for the lifetime of the application.
|
|
1382
1411
|
|
|
1383
1412
|
```typescript
|
|
1384
|
-
const C = TypeCompiler.Compile(Type.Object({
|
|
1385
|
-
x: Type.Number(),
|
|
1386
|
-
y: Type.Number(),
|
|
1387
|
-
z: Type.Number()
|
|
1388
|
-
}))
|
|
1413
|
+
const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObject<{
|
|
1414
|
+
x: Type.Number(), // x: TNumber;
|
|
1415
|
+
y: Type.Number(), // y: TNumber;
|
|
1416
|
+
z: Type.Number() // z: TNumber;
|
|
1417
|
+
})) // }>>
|
|
1389
1418
|
|
|
1390
|
-
const R = C.Check({ x: 1, y: 2, z: 3 })
|
|
1419
|
+
const R = C.Check({ x: 1, y: 2, z: 3 }) // const R = true
|
|
1391
1420
|
```
|
|
1392
1421
|
|
|
1393
|
-
Use the
|
|
1422
|
+
Use the Errors function to generate diagnostic errors for a value. The Errors function will return an iterator that when enumerated; will perform an exhaustive check across the entire value yielding any error found. For performance, this function should only be called after failed Check. Applications may also choose to yield only the first value to avoid exhaustive error generation.
|
|
1394
1423
|
|
|
1395
1424
|
```typescript
|
|
1396
|
-
const C = TypeCompiler.Compile(Type.Object({
|
|
1397
|
-
x: Type.Number(),
|
|
1398
|
-
y: Type.Number(),
|
|
1399
|
-
z: Type.Number()
|
|
1400
|
-
}))
|
|
1425
|
+
const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObject<{
|
|
1426
|
+
x: Type.Number(), // x: TNumber;
|
|
1427
|
+
y: Type.Number(), // y: TNumber;
|
|
1428
|
+
z: Type.Number() // z: TNumber;
|
|
1429
|
+
})) // }>>
|
|
1401
1430
|
|
|
1402
1431
|
const value = { }
|
|
1403
1432
|
|
|
1404
|
-
const
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
// schema: { type: 'number' },
|
|
1411
|
-
// path: '/y',
|
|
1412
|
-
// value: undefined,
|
|
1413
|
-
// message: 'Expected number'
|
|
1414
|
-
// }, {
|
|
1415
|
-
// schema: { type: 'number' },
|
|
1416
|
-
// path: '/z',
|
|
1417
|
-
// value: undefined,
|
|
1418
|
-
// message: 'Expected number'
|
|
1419
|
-
// }]
|
|
1420
|
-
```
|
|
1421
|
-
|
|
1422
|
-
Compiled routines can be inspected with the `.Code()` function.
|
|
1433
|
+
const first = C.Errors(value).First() // const first = {
|
|
1434
|
+
// schema: { type: 'number' },
|
|
1435
|
+
// path: '/x',
|
|
1436
|
+
// value: undefined,
|
|
1437
|
+
// message: 'Expected number'
|
|
1438
|
+
// }
|
|
1423
1439
|
|
|
1440
|
+
const all = [...C.Errors(value)] // const all = [{
|
|
1441
|
+
// schema: { type: 'number' },
|
|
1442
|
+
// path: '/x',
|
|
1443
|
+
// value: undefined,
|
|
1444
|
+
// message: 'Expected number'
|
|
1445
|
+
// }, {
|
|
1446
|
+
// schema: { type: 'number' },
|
|
1447
|
+
// path: '/y',
|
|
1448
|
+
// value: undefined,
|
|
1449
|
+
// message: 'Expected number'
|
|
1450
|
+
// }, {
|
|
1451
|
+
// schema: { type: 'number' },
|
|
1452
|
+
// path: '/z',
|
|
1453
|
+
// value: undefined,
|
|
1454
|
+
// message: 'Expected number'
|
|
1455
|
+
// }]
|
|
1456
|
+
```
|
|
1457
|
+
Use the Code function to generate assertion functions as strings. This function can be used to create high performance assertions that can be written to disk as importable modules. TypeBox supports both TypeScript and JavaScript code generation. The following generates TypeScript.
|
|
1424
1458
|
```typescript
|
|
1425
|
-
const C = TypeCompiler.
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
// )
|
|
1431
|
-
// }
|
|
1459
|
+
const C = TypeCompiler.Code(Type.String({ // const C = `return function check(value: any): boolean {
|
|
1460
|
+
language: 'typescript' // return (
|
|
1461
|
+
}) // (typeof value === 'string')
|
|
1462
|
+
// )
|
|
1463
|
+
// }`
|
|
1432
1464
|
```
|
|
1433
1465
|
|
|
1434
1466
|
<a name='typesystem'></a>
|
|
1435
1467
|
|
|
1436
1468
|
## TypeSystem
|
|
1437
1469
|
|
|
1438
|
-
The TypeBox TypeSystem
|
|
1439
|
-
|
|
1440
|
-
The TypeSystem module is provided as an optional import.
|
|
1441
|
-
|
|
1442
|
-
```typescript
|
|
1443
|
-
import { TypeSystem } from '@sinclair/typebox/system'
|
|
1444
|
-
```
|
|
1470
|
+
The TypeBox TypeSystem modules provides additional functionality to define types above and beyond the Json and JavaScript type sets. They also manage TypeBox's localization options (i18n) for error message generation and can control various internal assertion policies used for type checking. Configurations made to the TypeSystem module are observed by TypeCompiler, Value and Error modules.
|
|
1445
1471
|
|
|
1446
1472
|
<a name='typesystem-types'></a>
|
|
1447
1473
|
|
|
1448
1474
|
### Types
|
|
1449
1475
|
|
|
1450
|
-
Use the
|
|
1476
|
+
Use the TypeSystem Type function to register a user defined type.
|
|
1451
1477
|
|
|
1452
1478
|
```typescript
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
type Vector = { x: number, y: number }
|
|
1479
|
+
import { TypeSystem } from '@sinclair/typebox/system'
|
|
1456
1480
|
|
|
1457
|
-
const
|
|
1458
|
-
return (
|
|
1459
|
-
typeof value === 'object' && value !== null &&
|
|
1460
|
-
'x' in value && typeof value.x === 'number' &&
|
|
1461
|
-
'y' in value && typeof value.y === 'number' &&
|
|
1462
|
-
(options.abs ? (value.x === Math.abs(value.x) && value.y === Math.abs(value.y)) : true)
|
|
1463
|
-
)
|
|
1481
|
+
const StringSet = TypeSystem.Type<Set<string>>('StringSet', (options, value) => {
|
|
1482
|
+
return value instanceof Set && [...value].every(value => typeof value === 'string')
|
|
1464
1483
|
})
|
|
1465
1484
|
|
|
1466
|
-
const T =
|
|
1485
|
+
const T = StringSet({}) // Pass options if any
|
|
1467
1486
|
|
|
1468
|
-
|
|
1487
|
+
const A = Value.Check(T, new Set()) // const A = true
|
|
1469
1488
|
|
|
1470
|
-
const
|
|
1489
|
+
const B = Value.Check(T, new Set(['hello'])) // const B = true
|
|
1471
1490
|
|
|
1472
|
-
const
|
|
1491
|
+
const C = Value.Check(T, new Set([1])) // const C = false
|
|
1473
1492
|
|
|
1474
|
-
const R3 = Value.Check(T, { x: 1, y: -1 }) // const R3 = false
|
|
1475
1493
|
```
|
|
1476
1494
|
|
|
1477
1495
|
<a name='typesystem-formats'></a>
|
|
1478
1496
|
|
|
1479
1497
|
### Formats
|
|
1480
1498
|
|
|
1481
|
-
Use the
|
|
1499
|
+
Use the TypeSystem Format function to register a string format.
|
|
1482
1500
|
|
|
1483
1501
|
```typescript
|
|
1484
|
-
|
|
1502
|
+
import { TypeSystem } from '@sinclair/typebox/system'
|
|
1503
|
+
|
|
1504
|
+
const F = TypeSystem.Format('foo', value => value === 'Foo')
|
|
1485
1505
|
|
|
1486
|
-
const T = Type.String({ format:
|
|
1506
|
+
const T = Type.String({ format: F })
|
|
1487
1507
|
|
|
1488
|
-
const A = Value.Check(T, '
|
|
1508
|
+
const A = Value.Check(T, 'foo') // const A = true
|
|
1489
1509
|
|
|
1490
|
-
const B = Value.Check(T, '
|
|
1510
|
+
const B = Value.Check(T, 'bar') // const B = false
|
|
1511
|
+
```
|
|
1512
|
+
|
|
1513
|
+
<a name='typesystem-errors'></a>
|
|
1514
|
+
|
|
1515
|
+
### Errors
|
|
1516
|
+
|
|
1517
|
+
Use the TypeSystemErrorFunction module to override validation error message generation. This can be used to localize error messages or create custom errors for custom types.
|
|
1518
|
+
|
|
1519
|
+
```typescript
|
|
1520
|
+
import { TypeSystemErrorFunction, ValueErrorType, DefaultErrorFunction } from '@sinclair/typebox/system'
|
|
1521
|
+
|
|
1522
|
+
TypeSystemErrorFunction.Set((schema, errorType) => {// i18n override
|
|
1523
|
+
switch(errorType) {
|
|
1524
|
+
/* en-US */ case ValueErrorType.String: return 'Expected string'
|
|
1525
|
+
/* fr-FR */ case ValueErrorType.Number: return 'Nombre attendu'
|
|
1526
|
+
/* ko-KR */ case ValueErrorType.Boolean: return '예상 부울'
|
|
1527
|
+
/* en-US */ default: return DefaultErrorFunction(schema, errorType)
|
|
1528
|
+
}
|
|
1529
|
+
})
|
|
1530
|
+
const T = Type.Object({ // const T = { ... }
|
|
1531
|
+
x: Type.String(),
|
|
1532
|
+
y: Type.Number(),
|
|
1533
|
+
z: Type.Boolean()
|
|
1534
|
+
})
|
|
1535
|
+
const E = [...Value.Errors(T, { // const E = [{
|
|
1536
|
+
x: null, // type: 48,
|
|
1537
|
+
y: null, // schema: { ... },
|
|
1538
|
+
z: null // path: '/x',
|
|
1539
|
+
})] // value: null,
|
|
1540
|
+
// message: 'Expected string'
|
|
1541
|
+
// }, {
|
|
1542
|
+
// type: 34,
|
|
1543
|
+
// schema: { ... },
|
|
1544
|
+
// path: '/y',
|
|
1545
|
+
// value: null,
|
|
1546
|
+
// message: 'Nombre attendu'
|
|
1547
|
+
// }, {
|
|
1548
|
+
// type: 14,
|
|
1549
|
+
// schema: { ... },
|
|
1550
|
+
// path: '/z',
|
|
1551
|
+
// value: null,
|
|
1552
|
+
// message: '예상 부울'
|
|
1553
|
+
// }]
|
|
1491
1554
|
```
|
|
1492
1555
|
|
|
1493
1556
|
<a name='typesystem-policies'></a>
|
|
1494
1557
|
|
|
1495
1558
|
### Policies
|
|
1496
1559
|
|
|
1497
|
-
TypeBox
|
|
1560
|
+
TypeBox type checks using standard Json Schema assertion policies by default. The TypeSystemPolicy module can override some of these policies to have TypeBox check inline with TypeScript static assertions. It also provides overrides for certain checking policies related to non-serializable values (such as void) which can be useful in Json based protocols such as JsonRpc-2.
|
|
1561
|
+
|
|
1562
|
+
The following overrides are available.
|
|
1498
1563
|
|
|
1499
1564
|
```typescript
|
|
1565
|
+
import { TypeSystemPolicy } from '@sinclair/typebox/system'
|
|
1566
|
+
|
|
1500
1567
|
// Disallow undefined values for optional properties (default is false)
|
|
1501
1568
|
//
|
|
1502
1569
|
// const A: { x?: number } = { x: undefined } - disallowed when enabled
|
|
1503
1570
|
|
|
1504
|
-
|
|
1571
|
+
TypeSystemPolicy.ExactOptionalPropertyTypes = true
|
|
1505
1572
|
|
|
1506
1573
|
// Allow arrays to validate as object types (default is false)
|
|
1507
1574
|
//
|
|
1508
1575
|
// const A: {} = [] - allowed in TS
|
|
1509
1576
|
|
|
1510
|
-
|
|
1577
|
+
TypeSystemPolicy.AllowArrayObject = true
|
|
1511
1578
|
|
|
1512
1579
|
// Allow numeric values to be NaN or + or - Infinity (default is false)
|
|
1513
1580
|
//
|
|
1514
1581
|
// const A: number = NaN - allowed in TS
|
|
1515
1582
|
|
|
1516
|
-
|
|
1583
|
+
TypeSystemPolicy.AllowNaN = true
|
|
1584
|
+
|
|
1585
|
+
// Allow void type to check with undefined and null (default is false)
|
|
1586
|
+
//
|
|
1587
|
+
// Used to signal void return on Json-RPC 2.0 protocol
|
|
1588
|
+
|
|
1589
|
+
TypeSystemPolicy.AllowNullVoid = true
|
|
1517
1590
|
```
|
|
1518
1591
|
|
|
1519
1592
|
<a name='workbench'></a>
|
|
1520
1593
|
|
|
1521
1594
|
## TypeBox Workbench
|
|
1522
1595
|
|
|
1523
|
-
TypeBox offers a
|
|
1596
|
+
TypeBox offers a web based code generation tool that can convert TypeScript types into TypeBox types as well as several other ecosystem libraries.
|
|
1524
1597
|
|
|
1525
1598
|
[TypeBox Workbench Link Here](https://sinclairzx81.github.io/typebox-workbench/)
|
|
1526
1599
|
|
|
1600
|
+
<a name='codegen'></a>
|
|
1601
|
+
|
|
1602
|
+
## TypeBox Codegen
|
|
1603
|
+
|
|
1604
|
+
TypeBox provides an auxilary code generation library that can be used to automate type translation between TypeScript and TypeBox types. This library also includes functionality to transform other ecosystem libraries.
|
|
1605
|
+
|
|
1606
|
+
[TypeBox Codegen Link Here](https://github.com/sinclairzx81/typebox-codegen)
|
|
1607
|
+
|
|
1527
1608
|
<a name='ecosystem'></a>
|
|
1528
1609
|
|
|
1529
1610
|
## Ecosystem
|
|
1530
1611
|
|
|
1531
|
-
The following is a
|
|
1612
|
+
The following list is a set of community packages that offer general tooling, extended functionality and framework integration support for TypeBox.
|
|
1532
1613
|
|
|
1533
1614
|
| Package | Description |
|
|
1534
1615
|
| ------------- | ------------- |
|
|
@@ -1536,7 +1617,7 @@ The following is a list of community packages that provide general tooling and f
|
|
|
1536
1617
|
| [fastify-type-provider-typebox](https://github.com/fastify/fastify-type-provider-typebox) | Fastify TypeBox integration with the Fastify Type Provider |
|
|
1537
1618
|
| [feathersjs](https://github.com/feathersjs/feathers) | The API and real-time application framework |
|
|
1538
1619
|
| [fetch-typebox](https://github.com/erfanium/fetch-typebox) | Drop-in replacement for fetch that brings easy integration with TypeBox |
|
|
1539
|
-
| [schema2typebox](https://github.com/xddq/schema2typebox) | Creating TypeBox code from
|
|
1620
|
+
| [schema2typebox](https://github.com/xddq/schema2typebox) | Creating TypeBox code from Json Schemas |
|
|
1540
1621
|
| [ts2typebox](https://github.com/xddq/ts2typebox) | Creating TypeBox code from Typescript types |
|
|
1541
1622
|
| [typebox-client](https://github.com/flodlc/typebox-client) | Type safe http client library for Fastify |
|
|
1542
1623
|
| [typebox-validators](https://github.com/jtlapp/typebox-validators) | Advanced validators supporting discriminated and heterogeneous unions |
|
|
@@ -1559,35 +1640,35 @@ This benchmark measures compilation performance for varying types. You can revie
|
|
|
1559
1640
|
┌────────────────────────────┬────────────┬──────────────┬──────────────┬──────────────┐
|
|
1560
1641
|
│ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │
|
|
1561
1642
|
├────────────────────────────┼────────────┼──────────────┼──────────────┼──────────────┤
|
|
1562
|
-
│ Literal_String │ 1000 │ '
|
|
1563
|
-
│ Literal_Number │ 1000 │ '
|
|
1564
|
-
│ Literal_Boolean │ 1000 │ '
|
|
1565
|
-
│ Primitive_Number │ 1000 │ '
|
|
1566
|
-
│ Primitive_String │ 1000 │ '
|
|
1567
|
-
│ Primitive_String_Pattern │ 1000 │ '
|
|
1568
|
-
│ Primitive_Boolean │ 1000 │ '
|
|
1569
|
-
│ Primitive_Null │ 1000 │ '
|
|
1570
|
-
│ Object_Unconstrained │ 1000 │ '
|
|
1571
|
-
│ Object_Constrained │ 1000 │ '
|
|
1572
|
-
│ Object_Vector3 │ 1000 │ '
|
|
1573
|
-
│ Object_Box3D │ 1000 │ '
|
|
1574
|
-
│ Tuple_Primitive │ 1000 │ '
|
|
1575
|
-
│ Tuple_Object │ 1000 │ '
|
|
1576
|
-
│ Composite_Intersect │ 1000 │ '
|
|
1577
|
-
│ Composite_Union │ 1000 │ '
|
|
1578
|
-
│ Math_Vector4 │ 1000 │ '
|
|
1579
|
-
│ Math_Matrix4 │ 1000 │ '
|
|
1580
|
-
│ Array_Primitive_Number │ 1000 │ '
|
|
1581
|
-
│ Array_Primitive_String │ 1000 │ '
|
|
1582
|
-
│ Array_Primitive_Boolean │ 1000 │ '
|
|
1583
|
-
│ Array_Object_Unconstrained │ 1000 │ '
|
|
1584
|
-
│ Array_Object_Constrained │ 1000 │ '
|
|
1585
|
-
│ Array_Tuple_Primitive │ 1000 │ '
|
|
1586
|
-
│ Array_Tuple_Object │ 1000 │ '
|
|
1587
|
-
│ Array_Composite_Intersect │ 1000 │ '
|
|
1588
|
-
│ Array_Composite_Union │ 1000 │ '
|
|
1589
|
-
│ Array_Math_Vector4 │ 1000 │ '
|
|
1590
|
-
│ Array_Math_Matrix4 │ 1000 │ '
|
|
1643
|
+
│ Literal_String │ 1000 │ ' 216 ms' │ ' 9 ms' │ ' 24.00 x' │
|
|
1644
|
+
│ Literal_Number │ 1000 │ ' 169 ms' │ ' 7 ms' │ ' 24.14 x' │
|
|
1645
|
+
│ Literal_Boolean │ 1000 │ ' 150 ms' │ ' 5 ms' │ ' 30.00 x' │
|
|
1646
|
+
│ Primitive_Number │ 1000 │ ' 161 ms' │ ' 7 ms' │ ' 23.00 x' │
|
|
1647
|
+
│ Primitive_String │ 1000 │ ' 148 ms' │ ' 6 ms' │ ' 24.67 x' │
|
|
1648
|
+
│ Primitive_String_Pattern │ 1000 │ ' 185 ms' │ ' 9 ms' │ ' 20.56 x' │
|
|
1649
|
+
│ Primitive_Boolean │ 1000 │ ' 132 ms' │ ' 4 ms' │ ' 33.00 x' │
|
|
1650
|
+
│ Primitive_Null │ 1000 │ ' 141 ms' │ ' 3 ms' │ ' 47.00 x' │
|
|
1651
|
+
│ Object_Unconstrained │ 1000 │ ' 1109 ms' │ ' 30 ms' │ ' 36.97 x' │
|
|
1652
|
+
│ Object_Constrained │ 1000 │ ' 1200 ms' │ ' 24 ms' │ ' 50.00 x' │
|
|
1653
|
+
│ Object_Vector3 │ 1000 │ ' 379 ms' │ ' 9 ms' │ ' 42.11 x' │
|
|
1654
|
+
│ Object_Box3D │ 1000 │ ' 1709 ms' │ ' 30 ms' │ ' 56.97 x' │
|
|
1655
|
+
│ Tuple_Primitive │ 1000 │ ' 456 ms' │ ' 14 ms' │ ' 32.57 x' │
|
|
1656
|
+
│ Tuple_Object │ 1000 │ ' 1229 ms' │ ' 17 ms' │ ' 72.29 x' │
|
|
1657
|
+
│ Composite_Intersect │ 1000 │ ' 570 ms' │ ' 17 ms' │ ' 33.53 x' │
|
|
1658
|
+
│ Composite_Union │ 1000 │ ' 513 ms' │ ' 19 ms' │ ' 27.00 x' │
|
|
1659
|
+
│ Math_Vector4 │ 1000 │ ' 782 ms' │ ' 13 ms' │ ' 60.15 x' │
|
|
1660
|
+
│ Math_Matrix4 │ 1000 │ ' 393 ms' │ ' 12 ms' │ ' 32.75 x' │
|
|
1661
|
+
│ Array_Primitive_Number │ 1000 │ ' 361 ms' │ ' 12 ms' │ ' 30.08 x' │
|
|
1662
|
+
│ Array_Primitive_String │ 1000 │ ' 296 ms' │ ' 5 ms' │ ' 59.20 x' │
|
|
1663
|
+
│ Array_Primitive_Boolean │ 1000 │ ' 315 ms' │ ' 4 ms' │ ' 78.75 x' │
|
|
1664
|
+
│ Array_Object_Unconstrained │ 1000 │ ' 1721 ms' │ ' 22 ms' │ ' 78.23 x' │
|
|
1665
|
+
│ Array_Object_Constrained │ 1000 │ ' 1450 ms' │ ' 21 ms' │ ' 69.05 x' │
|
|
1666
|
+
│ Array_Tuple_Primitive │ 1000 │ ' 813 ms' │ ' 13 ms' │ ' 62.54 x' │
|
|
1667
|
+
│ Array_Tuple_Object │ 1000 │ ' 1537 ms' │ ' 17 ms' │ ' 90.41 x' │
|
|
1668
|
+
│ Array_Composite_Intersect │ 1000 │ ' 753 ms' │ ' 17 ms' │ ' 44.29 x' │
|
|
1669
|
+
│ Array_Composite_Union │ 1000 │ ' 808 ms' │ ' 16 ms' │ ' 50.50 x' │
|
|
1670
|
+
│ Array_Math_Vector4 │ 1000 │ ' 1118 ms' │ ' 16 ms' │ ' 69.88 x' │
|
|
1671
|
+
│ Array_Math_Matrix4 │ 1000 │ ' 690 ms' │ ' 9 ms' │ ' 76.67 x' │
|
|
1591
1672
|
└────────────────────────────┴────────────┴──────────────┴──────────────┴──────────────┘
|
|
1592
1673
|
```
|
|
1593
1674
|
|
|
@@ -1601,37 +1682,37 @@ This benchmark measures validation performance for varying types. You can review
|
|
|
1601
1682
|
┌────────────────────────────┬────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
|
|
1602
1683
|
│ (index) │ Iterations │ ValueCheck │ Ajv │ TypeCompiler │ Performance │
|
|
1603
1684
|
├────────────────────────────┼────────────┼──────────────┼──────────────┼──────────────┼──────────────┤
|
|
1604
|
-
│ Literal_String │ 1000000 │ '
|
|
1605
|
-
│ Literal_Number │ 1000000 │ ' 15 ms' │ '
|
|
1606
|
-
│ Literal_Boolean │ 1000000 │ '
|
|
1607
|
-
│ Primitive_Number │ 1000000 │ '
|
|
1608
|
-
│ Primitive_String │ 1000000 │ '
|
|
1609
|
-
│ Primitive_String_Pattern │ 1000000 │ '
|
|
1610
|
-
│ Primitive_Boolean │ 1000000 │ '
|
|
1611
|
-
│ Primitive_Null │ 1000000 │ '
|
|
1612
|
-
│ Object_Unconstrained │ 1000000 │ '
|
|
1613
|
-
│ Object_Constrained │ 1000000 │ '
|
|
1614
|
-
│ Object_Vector3 │ 1000000 │ '
|
|
1615
|
-
│ Object_Box3D │ 1000000 │ '
|
|
1616
|
-
│ Object_Recursive │ 1000000 │ '
|
|
1617
|
-
│ Tuple_Primitive │ 1000000 │ '
|
|
1618
|
-
│ Tuple_Object │ 1000000 │ '
|
|
1619
|
-
│ Composite_Intersect │ 1000000 │ '
|
|
1620
|
-
│ Composite_Union │ 1000000 │ '
|
|
1621
|
-
│ Math_Vector4 │ 1000000 │ '
|
|
1622
|
-
│ Math_Matrix4 │ 1000000 │ '
|
|
1623
|
-
│ Array_Primitive_Number │ 1000000 │ '
|
|
1624
|
-
│ Array_Primitive_String │ 1000000 │ '
|
|
1625
|
-
│ Array_Primitive_Boolean │ 1000000 │ '
|
|
1626
|
-
│ Array_Object_Unconstrained │ 1000000 │ '
|
|
1627
|
-
│ Array_Object_Constrained │ 1000000 │ '
|
|
1628
|
-
│ Array_Object_Recursive │ 1000000 │ '
|
|
1629
|
-
│ Array_Tuple_Primitive │ 1000000 │ '
|
|
1630
|
-
│ Array_Tuple_Object │ 1000000 │ '
|
|
1631
|
-
│ Array_Composite_Intersect │ 1000000 │ '
|
|
1632
|
-
│ Array_Composite_Union │ 1000000 │ '
|
|
1633
|
-
│ Array_Math_Vector4 │ 1000000 │ '
|
|
1634
|
-
│ Array_Math_Matrix4 │ 1000000 │ '
|
|
1685
|
+
│ Literal_String │ 1000000 │ ' 24 ms' │ ' 5 ms' │ ' 4 ms' │ ' 1.25 x' │
|
|
1686
|
+
│ Literal_Number │ 1000000 │ ' 15 ms' │ ' 20 ms' │ ' 10 ms' │ ' 2.00 x' │
|
|
1687
|
+
│ Literal_Boolean │ 1000000 │ ' 14 ms' │ ' 19 ms' │ ' 9 ms' │ ' 2.11 x' │
|
|
1688
|
+
│ Primitive_Number │ 1000000 │ ' 25 ms' │ ' 18 ms' │ ' 10 ms' │ ' 1.80 x' │
|
|
1689
|
+
│ Primitive_String │ 1000000 │ ' 21 ms' │ ' 24 ms' │ ' 9 ms' │ ' 2.67 x' │
|
|
1690
|
+
│ Primitive_String_Pattern │ 1000000 │ ' 156 ms' │ ' 43 ms' │ ' 38 ms' │ ' 1.13 x' │
|
|
1691
|
+
│ Primitive_Boolean │ 1000000 │ ' 18 ms' │ ' 17 ms' │ ' 9 ms' │ ' 1.89 x' │
|
|
1692
|
+
│ Primitive_Null │ 1000000 │ ' 20 ms' │ ' 17 ms' │ ' 9 ms' │ ' 1.89 x' │
|
|
1693
|
+
│ Object_Unconstrained │ 1000000 │ ' 1055 ms' │ ' 32 ms' │ ' 24 ms' │ ' 1.33 x' │
|
|
1694
|
+
│ Object_Constrained │ 1000000 │ ' 1232 ms' │ ' 49 ms' │ ' 43 ms' │ ' 1.14 x' │
|
|
1695
|
+
│ Object_Vector3 │ 1000000 │ ' 432 ms' │ ' 23 ms' │ ' 13 ms' │ ' 1.77 x' │
|
|
1696
|
+
│ Object_Box3D │ 1000000 │ ' 1993 ms' │ ' 54 ms' │ ' 46 ms' │ ' 1.17 x' │
|
|
1697
|
+
│ Object_Recursive │ 1000000 │ ' 5115 ms' │ ' 342 ms' │ ' 159 ms' │ ' 2.15 x' │
|
|
1698
|
+
│ Tuple_Primitive │ 1000000 │ ' 156 ms' │ ' 21 ms' │ ' 13 ms' │ ' 1.62 x' │
|
|
1699
|
+
│ Tuple_Object │ 1000000 │ ' 740 ms' │ ' 29 ms' │ ' 18 ms' │ ' 1.61 x' │
|
|
1700
|
+
│ Composite_Intersect │ 1000000 │ ' 797 ms' │ ' 26 ms' │ ' 14 ms' │ ' 1.86 x' │
|
|
1701
|
+
│ Composite_Union │ 1000000 │ ' 530 ms' │ ' 23 ms' │ ' 13 ms' │ ' 1.77 x' │
|
|
1702
|
+
│ Math_Vector4 │ 1000000 │ ' 240 ms' │ ' 22 ms' │ ' 11 ms' │ ' 2.00 x' │
|
|
1703
|
+
│ Math_Matrix4 │ 1000000 │ ' 1036 ms' │ ' 39 ms' │ ' 27 ms' │ ' 1.44 x' │
|
|
1704
|
+
│ Array_Primitive_Number │ 1000000 │ ' 248 ms' │ ' 20 ms' │ ' 12 ms' │ ' 1.67 x' │
|
|
1705
|
+
│ Array_Primitive_String │ 1000000 │ ' 227 ms' │ ' 22 ms' │ ' 13 ms' │ ' 1.69 x' │
|
|
1706
|
+
│ Array_Primitive_Boolean │ 1000000 │ ' 138 ms' │ ' 21 ms' │ ' 13 ms' │ ' 1.62 x' │
|
|
1707
|
+
│ Array_Object_Unconstrained │ 1000000 │ ' 5540 ms' │ ' 66 ms' │ ' 59 ms' │ ' 1.12 x' │
|
|
1708
|
+
│ Array_Object_Constrained │ 1000000 │ ' 5750 ms' │ ' 123 ms' │ ' 108 ms' │ ' 1.14 x' │
|
|
1709
|
+
│ Array_Object_Recursive │ 1000000 │ ' 21842 ms' │ ' 1771 ms' │ ' 599 ms' │ ' 2.96 x' │
|
|
1710
|
+
│ Array_Tuple_Primitive │ 1000000 │ ' 715 ms' │ ' 36 ms' │ ' 29 ms' │ ' 1.24 x' │
|
|
1711
|
+
│ Array_Tuple_Object │ 1000000 │ ' 3131 ms' │ ' 63 ms' │ ' 50 ms' │ ' 1.26 x' │
|
|
1712
|
+
│ Array_Composite_Intersect │ 1000000 │ ' 3064 ms' │ ' 44 ms' │ ' 35 ms' │ ' 1.26 x' │
|
|
1713
|
+
│ Array_Composite_Union │ 1000000 │ ' 2172 ms' │ ' 65 ms' │ ' 31 ms' │ ' 2.10 x' │
|
|
1714
|
+
│ Array_Math_Vector4 │ 1000000 │ ' 1032 ms' │ ' 37 ms' │ ' 24 ms' │ ' 1.54 x' │
|
|
1715
|
+
│ Array_Math_Matrix4 │ 1000000 │ ' 4859 ms' │ ' 114 ms' │ ' 86 ms' │ ' 1.33 x' │
|
|
1635
1716
|
└────────────────────────────┴────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
|
|
1636
1717
|
```
|
|
1637
1718
|
|
|
@@ -1645,11 +1726,11 @@ The following table lists esbuild compiled and minified sizes for each TypeBox m
|
|
|
1645
1726
|
┌──────────────────────┬────────────┬────────────┬─────────────┐
|
|
1646
1727
|
│ (index) │ Compiled │ Minified │ Compression │
|
|
1647
1728
|
├──────────────────────┼────────────┼────────────┼─────────────┤
|
|
1648
|
-
│ typebox/compiler │ '
|
|
1649
|
-
│ typebox/errors │ '
|
|
1650
|
-
│ typebox/system │ '
|
|
1651
|
-
│ typebox/value │ '
|
|
1652
|
-
│ typebox │ '
|
|
1729
|
+
│ typebox/compiler │ '148.9 kb' │ ' 65.8 kb' │ '2.26 x' │
|
|
1730
|
+
│ typebox/errors │ '111.5 kb' │ ' 49.1 kb' │ '2.27 x' │
|
|
1731
|
+
│ typebox/system │ ' 82.6 kb' │ ' 36.8 kb' │ '2.24 x' │
|
|
1732
|
+
│ typebox/value │ '190.5 kb' │ ' 82.4 kb' │ '2.31 x' │
|
|
1733
|
+
│ typebox │ ' 72.4 kb' │ ' 31.6 kb' │ '2.29 x' │
|
|
1653
1734
|
└──────────────────────┴────────────┴────────────┴─────────────┘
|
|
1654
1735
|
```
|
|
1655
1736
|
|