@sinclair/typebox 0.23.4 → 0.24.1
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 +25 -0
- package/compiler/compiler.js +347 -0
- package/compiler/index.d.ts +1 -0
- package/compiler/index.js +40 -0
- package/license +1 -1
- package/package.json +6 -6
- package/readme.md +377 -361
- package/typebox.d.ts +306 -296
- package/typebox.js +247 -260
- package/value/check.d.ts +5 -0
- package/value/check.js +232 -0
- package/value/clone.d.ts +3 -0
- package/value/clone.js +94 -0
- package/value/create.d.ts +7 -0
- package/value/create.js +337 -0
- package/value/delta.d.ts +13 -0
- package/value/delta.js +191 -0
- package/value/index.d.ts +1 -0
- package/value/index.js +40 -0
- package/value/pointer.d.ts +12 -0
- package/value/pointer.js +110 -0
- package/value/reflect.d.ts +2 -0
- package/value/reflect.js +42 -0
- package/value/upcast.d.ts +4 -0
- package/value/upcast.js +247 -0
- package/value/value.d.ts +17 -0
- package/value/value.js +70 -0
package/readme.md
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
<h1>TypeBox</h1>
|
|
4
4
|
|
|
5
|
-
<img src="https://github.com/sinclairzx81/typebox/blob/master/typebox.png?raw=true" />
|
|
6
|
-
|
|
7
5
|
<p>JSON Schema Type Builder with Static Type Resolution for TypeScript</p>
|
|
6
|
+
|
|
7
|
+
<img src="https://github.com/sinclairzx81/typebox/blob/master/typebox.png?raw=true" />
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
<br />
|
|
10
|
+
<br />
|
|
10
11
|
|
|
11
12
|
[](https://badge.fury.io/js/%40sinclair%2Ftypebox) [](https://github.com/sinclairzx81/typebox/actions)
|
|
12
13
|
|
|
@@ -33,7 +34,7 @@ import { Static, Type } from 'https://deno.land/x/typebox/src/typebox.ts'
|
|
|
33
34
|
```typescript
|
|
34
35
|
import { Static, Type } from '@sinclair/typebox'
|
|
35
36
|
|
|
36
|
-
const T = Type.String() // const T = {
|
|
37
|
+
const T = Type.String() // const T = { type: 'string' }
|
|
37
38
|
|
|
38
39
|
type T = Static<typeof T> // type T = string
|
|
39
40
|
```
|
|
@@ -42,11 +43,9 @@ type T = Static<typeof T> // type T = string
|
|
|
42
43
|
|
|
43
44
|
## Overview
|
|
44
45
|
|
|
45
|
-
TypeBox is a 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 allows one to
|
|
46
|
-
|
|
47
|
-
TypeBox can be used as a simple tool to build up complex schemas or integrated into RPC or REST services to help validate JSON data received over the wire. TypeBox does not provide any JSON schema validation. Please use libraries such as AJV to validate schemas built with this library.
|
|
46
|
+
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 allows one to compose unified types that can be statically asserted by the TypeScript compiler as well as runtime asserted using standard JSON Schema validation.
|
|
48
47
|
|
|
49
|
-
|
|
48
|
+
TypeBox can be used as a simple tool to build up complex schemas or integrated into RPC or REST services to help validate JSON data received over the wire. It can be used in both TypeScript and JavaScript environments.
|
|
50
49
|
|
|
51
50
|
License MIT
|
|
52
51
|
|
|
@@ -57,13 +56,16 @@ License MIT
|
|
|
57
56
|
- [Types](#Types)
|
|
58
57
|
- [Modifiers](#Modifiers)
|
|
59
58
|
- [Options](#Options)
|
|
60
|
-
- [
|
|
59
|
+
- [Extended Types](#Extended-Types)
|
|
61
60
|
- [Reference Types](#Reference-Types)
|
|
62
61
|
- [Recursive Types](#Recursive-Types)
|
|
63
|
-
- [
|
|
62
|
+
- [Generic Types](#Generic-Types)
|
|
63
|
+
- [Unsafe Types](#Unsafe-Types)
|
|
64
|
+
- [Values](#Values)
|
|
64
65
|
- [Strict](#Strict)
|
|
65
66
|
- [Validation](#Validation)
|
|
66
|
-
- [
|
|
67
|
+
- [Compiler](#Compiler)
|
|
68
|
+
- [Contribute](#Contribute)
|
|
67
69
|
|
|
68
70
|
<a name="Example"></a>
|
|
69
71
|
|
|
@@ -82,9 +84,9 @@ import { Static, Type } from '@sinclair/typebox'
|
|
|
82
84
|
//--------------------------------------------------------------------------------------------
|
|
83
85
|
|
|
84
86
|
type T = {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
id: string,
|
|
88
|
+
name: string,
|
|
89
|
+
timestamp: number
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
//--------------------------------------------------------------------------------------------
|
|
@@ -93,25 +95,25 @@ type T = {
|
|
|
93
95
|
//
|
|
94
96
|
//--------------------------------------------------------------------------------------------
|
|
95
97
|
|
|
96
|
-
const T = Type.Object({
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
98
|
+
const T = Type.Object({ // const T = {
|
|
99
|
+
id: Type.String(), // type: 'object',
|
|
100
|
+
name: Type.String(), // properties: {
|
|
101
|
+
timestamp: Type.Integer() // id: {
|
|
102
|
+
}) // type: 'string'
|
|
103
|
+
// },
|
|
104
|
+
// name: {
|
|
105
|
+
// type: 'string'
|
|
106
|
+
// },
|
|
107
|
+
// timestamp: {
|
|
108
|
+
// type: 'integer'
|
|
109
|
+
// }
|
|
110
|
+
// },
|
|
111
|
+
// required: [
|
|
112
|
+
// "id",
|
|
113
|
+
// "name",
|
|
114
|
+
// "timestamp"
|
|
115
|
+
// ]
|
|
116
|
+
// }
|
|
115
117
|
|
|
116
118
|
//--------------------------------------------------------------------------------------------
|
|
117
119
|
//
|
|
@@ -119,11 +121,11 @@ const T = Type.Object({ // const T = {
|
|
|
119
121
|
//
|
|
120
122
|
//--------------------------------------------------------------------------------------------
|
|
121
123
|
|
|
122
|
-
type T = Static<typeof T>
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
type T = Static<typeof T> // type T = {
|
|
125
|
+
// id: string,
|
|
126
|
+
// name: string,
|
|
127
|
+
// timestamp: number
|
|
128
|
+
// }
|
|
127
129
|
|
|
128
130
|
//--------------------------------------------------------------------------------------------
|
|
129
131
|
//
|
|
@@ -131,12 +133,11 @@ type T = Static<typeof T> // type T = {
|
|
|
131
133
|
//
|
|
132
134
|
//--------------------------------------------------------------------------------------------
|
|
133
135
|
|
|
134
|
-
function receive(value: T) {
|
|
135
|
-
|
|
136
|
-
if(JSON.validate(T, value)) { // ... as a Schema
|
|
136
|
+
function receive(value: T) { // ... as a Type
|
|
137
137
|
|
|
138
|
+
if(JSON.validate(T, value)) { // ... as a Schema
|
|
138
139
|
// ok...
|
|
139
|
-
|
|
140
|
+
}
|
|
140
141
|
}
|
|
141
142
|
```
|
|
142
143
|
|
|
@@ -158,22 +159,22 @@ The following table outlines the TypeBox mappings between TypeScript and JSON sc
|
|
|
158
159
|
│ │ │ │
|
|
159
160
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
160
161
|
│ const T = Type.String() │ type T = string │ const T = { │
|
|
161
|
-
│ │ │
|
|
162
|
+
│ │ │ type: 'string' │
|
|
162
163
|
│ │ │ } │
|
|
163
164
|
│ │ │ │
|
|
164
165
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
165
166
|
│ const T = Type.Number() │ type T = number │ const T = { │
|
|
166
|
-
│ │ │
|
|
167
|
+
│ │ │ type: 'number' │
|
|
167
168
|
│ │ │ } │
|
|
168
169
|
│ │ │ │
|
|
169
170
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
170
171
|
│ const T = Type.Integer() │ type T = number │ const T = { │
|
|
171
|
-
│ │ │
|
|
172
|
+
│ │ │ type: 'integer' │
|
|
172
173
|
│ │ │ } │
|
|
173
174
|
│ │ │ │
|
|
174
175
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
175
176
|
│ const T = Type.Boolean() │ type T = boolean │ const T = { │
|
|
176
|
-
│ │ │
|
|
177
|
+
│ │ │ type: 'boolean' │
|
|
177
178
|
│ │ │ } │
|
|
178
179
|
│ │ │ │
|
|
179
180
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
@@ -195,16 +196,16 @@ The following table outlines the TypeBox mappings between TypeScript and JSON sc
|
|
|
195
196
|
│ │ │ │
|
|
196
197
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
197
198
|
│ const T = Type.Array( │ type T = number[] │ const T = { │
|
|
198
|
-
│
|
|
199
|
-
│ ) │ │
|
|
200
|
-
│ │ │
|
|
201
|
-
│ │ │
|
|
199
|
+
│ Type.Number() │ │ type: 'array', │
|
|
200
|
+
│ ) │ │ items: { │
|
|
201
|
+
│ │ │ type: 'number' │
|
|
202
|
+
│ │ │ } │
|
|
202
203
|
│ │ │ } │
|
|
203
204
|
│ │ │ │
|
|
204
205
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
205
206
|
│ const T = Type.Object({ │ type T = { │ const T = { │
|
|
206
|
-
│ x: Type.Number(), │
|
|
207
|
-
│ y: Type.Number() │
|
|
207
|
+
│ x: Type.Number(), │ x: number, │ type: 'object', │
|
|
208
|
+
│ y: Type.Number() │ y: number │ properties: { │
|
|
208
209
|
│ }) │ } │ x: { │
|
|
209
210
|
│ │ │ type: 'number' │
|
|
210
211
|
│ │ │ }, │
|
|
@@ -217,19 +218,18 @@ The following table outlines the TypeBox mappings between TypeScript and JSON sc
|
|
|
217
218
|
│ │ │ │
|
|
218
219
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
219
220
|
│ const T = Type.Tuple([ │ type T = [number, number] │ const T = { │
|
|
220
|
-
│ Type.Number(), │ │
|
|
221
|
-
│ Type.Number() │ │
|
|
222
|
-
│ ]) │ │
|
|
223
|
-
│ │ │
|
|
224
|
-
│ │ │
|
|
225
|
-
│ │ │
|
|
226
|
-
│ │ │ } │
|
|
227
|
-
│ │ │ ], │
|
|
221
|
+
│ Type.Number(), │ │ type: 'array', │
|
|
222
|
+
│ Type.Number() │ │ items: [{ │
|
|
223
|
+
│ ]) │ │ type: 'number' │
|
|
224
|
+
│ │ │ }, { │
|
|
225
|
+
│ │ │ type: 'number' │
|
|
226
|
+
│ │ │ }], │
|
|
228
227
|
│ │ │ additionalItems: false, │
|
|
229
228
|
│ │ │ minItems: 2, │
|
|
230
229
|
│ │ │ maxItems: 2, │
|
|
231
230
|
│ │ │ } │
|
|
232
231
|
│ │ │ │
|
|
232
|
+
│ │ │ │
|
|
233
233
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
234
234
|
│ enum Foo { │ enum Foo { │ const T = { │
|
|
235
235
|
│ A, │ A, │ anyOf: [{ │
|
|
@@ -243,85 +243,81 @@ The following table outlines the TypeBox mappings between TypeScript and JSON sc
|
|
|
243
243
|
│ │ │ │
|
|
244
244
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
245
245
|
│ const T = Type.KeyOf( │ type T = keyof { │ const T = { │
|
|
246
|
-
│ Type.Object({ │ x: number, │
|
|
247
|
-
│ x: Type.Number(), │ y: number │
|
|
248
|
-
│ y: Type.Number() │ } │
|
|
249
|
-
│ }) │ │
|
|
250
|
-
│ ) │ │
|
|
246
|
+
│ Type.Object({ │ x: number, │ anyOf: [{ │
|
|
247
|
+
│ x: Type.Number(), │ y: number │ type: 'string', │
|
|
248
|
+
│ y: Type.Number() │ } │ const: 'x' │
|
|
249
|
+
│ }) │ │ }, { │
|
|
250
|
+
│ ) │ │ type: 'string', │
|
|
251
|
+
│ │ │ const: 'y', │
|
|
252
|
+
│ │ │ }] │
|
|
253
|
+
│ │ │ } │
|
|
251
254
|
│ │ │ │
|
|
252
255
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
253
256
|
│ const T = Type.Union([ │ type T = string | number │ const T = { │
|
|
254
|
-
│ Type.String(), │ │
|
|
255
|
-
│ Type.Number() │ │
|
|
256
|
-
│ ]) │ │
|
|
257
|
-
│ │ │
|
|
258
|
-
│ │ │
|
|
257
|
+
│ Type.String(), │ │ anyOf: [{ │
|
|
258
|
+
│ Type.Number() │ │ type: 'string' │
|
|
259
|
+
│ ]) │ │ }, { │
|
|
260
|
+
│ │ │ type: 'number' │
|
|
261
|
+
│ │ │ }] │
|
|
259
262
|
│ │ │ } │
|
|
260
263
|
│ │ │ │
|
|
261
264
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
262
265
|
│ const T = Type.Intersect([ │ type T = { │ const T = { │
|
|
263
|
-
│
|
|
264
|
-
│
|
|
265
|
-
│
|
|
266
|
-
│
|
|
267
|
-
│
|
|
268
|
-
│ }) │ │
|
|
269
|
-
│
|
|
270
|
-
│ │ │
|
|
271
|
-
│ │ │
|
|
272
|
-
│ │ │
|
|
273
|
-
│ │ │ properties: { │
|
|
274
|
-
│ │ │ y: { │
|
|
275
|
-
│ │ │ type: 'number' │
|
|
276
|
-
│ │ │ } │
|
|
277
|
-
│ │ │ }, │
|
|
278
|
-
│ │ │ required: ['y'] │
|
|
279
|
-
│ │ │ }] │
|
|
266
|
+
│ Type.Object({ │ x: number │ type: 'object', │
|
|
267
|
+
│ x: Type.Number() │ } & { │ properties: { │
|
|
268
|
+
│ }), │ y: number │ x: { │
|
|
269
|
+
│ Type.Object({ │ } │ type: 'number' │
|
|
270
|
+
│ y: Type.Number() │ │ }, │
|
|
271
|
+
│ }) │ │ y: { │
|
|
272
|
+
│ ]) │ │ type: 'number' │
|
|
273
|
+
│ │ │ } │
|
|
274
|
+
│ │ │ }, │
|
|
275
|
+
│ │ │ required: ['x', 'y'] │
|
|
280
276
|
│ │ │ } │
|
|
281
277
|
│ │ │ │
|
|
282
278
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
283
|
-
│ const T = Type.Record( │ type T =
|
|
284
|
-
│
|
|
285
|
-
│
|
|
286
|
-
│ ) │
|
|
287
|
-
│ │ │
|
|
288
|
-
│ │ │
|
|
289
|
-
│ │ │
|
|
279
|
+
│ const T = Type.Record( │ type T = Record< │ const T = { │
|
|
280
|
+
│ Type.String(), │ string, │ type: 'object', │
|
|
281
|
+
│ Type.Number() │ number, │ patternProperties: { │
|
|
282
|
+
│ ) │ > │ '^.*$': { │
|
|
283
|
+
│ │ │ type: 'number' │
|
|
284
|
+
│ │ │ } │
|
|
285
|
+
│ │ │ } │
|
|
290
286
|
│ │ │ } │
|
|
291
287
|
│ │ │ │
|
|
292
288
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
293
289
|
│ const T = Type.Partial( │ type T = Partial<{ │ const T = { │
|
|
294
|
-
│
|
|
295
|
-
│
|
|
296
|
-
│
|
|
297
|
-
│
|
|
290
|
+
│ Type.Object({ │ x: number, │ type: 'object', │
|
|
291
|
+
│ x: Type.Number(), │ y: number │ properties: { │
|
|
292
|
+
│ y: Type.Number() | }> │ x: { │
|
|
293
|
+
│ }) │ │ type: 'number' │
|
|
298
294
|
│ ) │ │ }, │
|
|
299
295
|
│ │ │ y: { │
|
|
300
|
-
│ │ │
|
|
296
|
+
│ │ │ type: 'number' │
|
|
301
297
|
│ │ │ } │
|
|
302
298
|
│ │ │ } │
|
|
303
299
|
│ │ │ } │
|
|
304
300
|
│ │ │ │
|
|
305
301
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
306
302
|
│ const T = Type.Required( │ type T = Required<{ │ const T = { │
|
|
307
|
-
│
|
|
308
|
-
│
|
|
309
|
-
│
|
|
310
|
-
│
|
|
311
|
-
│
|
|
312
|
-
│
|
|
313
|
-
│
|
|
314
|
-
│
|
|
303
|
+
│ Type.Object({ │ x?: number, │ type: 'object', │
|
|
304
|
+
│ x: Type.Optional( │ y?: number │ properties: { │
|
|
305
|
+
│ Type.Number() | }> │ x: { │
|
|
306
|
+
│ ), │ │ type: 'number' │
|
|
307
|
+
│ y: Type.Optional( │ │ }, │
|
|
308
|
+
│ Type.Number() │ │ y: { │
|
|
309
|
+
│ ) │ │ type: 'number' │
|
|
310
|
+
│ }) │ │ } │
|
|
315
311
|
│ ) │ │ }, │
|
|
316
312
|
│ │ │ required: ['x', 'y'] │
|
|
317
313
|
│ │ │ } │
|
|
318
314
|
│ │ │ │
|
|
319
315
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
320
316
|
│ const T = Type.Pick( │ type T = Pick<{ │ const T = { │
|
|
321
|
-
│
|
|
322
|
-
│
|
|
323
|
-
│
|
|
324
|
-
│
|
|
317
|
+
│ Type.Object({ │ x: number, │ type: 'object', │
|
|
318
|
+
│ x: Type.Number(), │ y: number │ properties: { │
|
|
319
|
+
│ y: Type.Number(), | }, 'x'> │ x: { │
|
|
320
|
+
│ }), ['x'] │ │ type: 'number' │
|
|
325
321
|
│ ) │ │ } │
|
|
326
322
|
│ │ │ }, │
|
|
327
323
|
│ │ │ required: ['x'] │
|
|
@@ -329,10 +325,10 @@ The following table outlines the TypeBox mappings between TypeScript and JSON sc
|
|
|
329
325
|
│ │ │ │
|
|
330
326
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
331
327
|
│ const T = Type.Omit( │ type T = Omit<{ │ const T = { │
|
|
332
|
-
│
|
|
333
|
-
│
|
|
334
|
-
│
|
|
335
|
-
│
|
|
328
|
+
│ Type.Object({ │ x: number, │ type: 'object', │
|
|
329
|
+
│ x: Type.Number(), │ y: number │ properties: { │
|
|
330
|
+
│ y: Type.Number(), | }, 'x'> │ y: { │
|
|
331
|
+
│ }), ['x'] │ │ type: 'number' │
|
|
336
332
|
│ ) │ │ } │
|
|
337
333
|
│ │ │ }, │
|
|
338
334
|
│ │ │ required: ['y'] │
|
|
@@ -352,8 +348,8 @@ TypeBox provides modifiers that can be applied to an objects properties. This al
|
|
|
352
348
|
│ │ │ │
|
|
353
349
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
354
350
|
│ const T = Type.Object({ │ type T = { │ const T = { │
|
|
355
|
-
│ name: Type.Optional( │
|
|
356
|
-
│
|
|
351
|
+
│ name: Type.Optional( │ name?: string, │ type: 'object', │
|
|
352
|
+
│ Type.String(), │ } │ properties: { │
|
|
357
353
|
│ ) │ │ name: { │
|
|
358
354
|
│ }) │ │ type: 'string' │
|
|
359
355
|
│ │ │ } │
|
|
@@ -362,22 +358,22 @@ TypeBox provides modifiers that can be applied to an objects properties. This al
|
|
|
362
358
|
│ │ │ │
|
|
363
359
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
364
360
|
│ const T = Type.Object({ │ type T = { │ const T = { │
|
|
365
|
-
│ name: Type.Readonly( │
|
|
366
|
-
│
|
|
367
|
-
│ ) │ │
|
|
368
|
-
│ }) │ │
|
|
369
|
-
│ │ │
|
|
361
|
+
│ name: Type.Readonly( │ readonly name: string, │ type: 'object', │
|
|
362
|
+
│ Type.String(), │ } │ properties: { │
|
|
363
|
+
│ ) │ │ name: { │
|
|
364
|
+
│ }) │ │ type: 'string' │
|
|
365
|
+
│ │ │ } │
|
|
370
366
|
│ │ │ }, │
|
|
371
367
|
│ │ │ required: ['name'] │
|
|
372
368
|
│ │ │ } │
|
|
373
369
|
│ │ │ │
|
|
374
370
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
375
371
|
│ const T = Type.Object({ │ type T = { │ const T = { │
|
|
376
|
-
│ name: Type.ReadonlyOptional( │
|
|
377
|
-
│
|
|
378
|
-
│ ) │ │
|
|
379
|
-
│ }) │ │
|
|
380
|
-
│ │ │
|
|
372
|
+
│ name: Type.ReadonlyOptional( │ readonly name?: string │ type: 'object', │
|
|
373
|
+
│ Type.String(), │ } │ properties: { │
|
|
374
|
+
│ ) │ │ name: { │
|
|
375
|
+
│ }) │ │ type: 'string' │
|
|
376
|
+
│ │ │ } │
|
|
381
377
|
│ │ │ } │
|
|
382
378
|
│ │ │ } │
|
|
383
379
|
│ │ │ │
|
|
@@ -400,142 +396,6 @@ const T = Type.Number({ multipleOf: 2 })
|
|
|
400
396
|
// array must have at least 5 integer values
|
|
401
397
|
const T = Type.Array(Type.Integer(), { minItems: 5 })
|
|
402
398
|
```
|
|
403
|
-
<a name="Generic-Types"></a>
|
|
404
|
-
|
|
405
|
-
### Generic Types
|
|
406
|
-
|
|
407
|
-
Generic types can be created using functions. The following creates a generic `Nullable<T>` type.
|
|
408
|
-
|
|
409
|
-
```typescript
|
|
410
|
-
import { Type, Static, TSchema } from '@sinclair/typebox'
|
|
411
|
-
|
|
412
|
-
// type Nullable<T> = T | null
|
|
413
|
-
|
|
414
|
-
const Nullable = <T extends TSchema>(type: T) => Type.Union([type, Type.Null()])
|
|
415
|
-
|
|
416
|
-
const T = Nullable(Type.String()) // const T = {
|
|
417
|
-
// "anyOf": [{
|
|
418
|
-
// type: 'string'
|
|
419
|
-
// }, {
|
|
420
|
-
// type: 'null'
|
|
421
|
-
// }]
|
|
422
|
-
// }
|
|
423
|
-
|
|
424
|
-
type T = Static<typeof T> // type T = string | null
|
|
425
|
-
|
|
426
|
-
const U = Nullable(Type.Number()) // const U = {
|
|
427
|
-
// "anyOf": [{
|
|
428
|
-
// type: 'number'
|
|
429
|
-
// }, {
|
|
430
|
-
// type: 'null'
|
|
431
|
-
// }]
|
|
432
|
-
// }
|
|
433
|
-
|
|
434
|
-
type U = Static<typeof U> // type U = number | null
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
<a name="Reference-Types"></a>
|
|
438
|
-
|
|
439
|
-
### Reference Types
|
|
440
|
-
|
|
441
|
-
Types can be referenced with `Type.Ref(...)`. To reference a type, the target type must specify an `$id`.
|
|
442
|
-
|
|
443
|
-
```typescript
|
|
444
|
-
const T = Type.String({ $id: 'T' }) // const T = {
|
|
445
|
-
// $id: 'T',
|
|
446
|
-
// type: 'string'
|
|
447
|
-
// }
|
|
448
|
-
|
|
449
|
-
const R = Type.Ref(T) // const R = {
|
|
450
|
-
// $ref: 'T'
|
|
451
|
-
// }
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
It can sometimes be helpful to organize shared referenced types under a common namespace. The `Type.Namespace(...)` function can be used to create a shared definition container for related types. The following creates a `Math3D` container and a `Vertex` structure that references types in the container.
|
|
455
|
-
|
|
456
|
-
```typescript
|
|
457
|
-
const Math3D = Type.Namespace({ // const Math3D = {
|
|
458
|
-
Vector4: Type.Object({ // $id: 'Math3D',
|
|
459
|
-
x: Type.Number(), // $defs: {
|
|
460
|
-
y: Type.Number(), // Vector4: {
|
|
461
|
-
z: Type.Number(), // type: 'object',
|
|
462
|
-
w: Type.Number() // properties: {
|
|
463
|
-
}), // x: { type: 'number' },
|
|
464
|
-
Vector3: Type.Object({ // y: { type: 'number' },
|
|
465
|
-
x: Type.Number(), // z: { type: 'number' },
|
|
466
|
-
y: Type.Number(), // w: { type: 'number' }
|
|
467
|
-
z: Type.Number() // },
|
|
468
|
-
}), // required: ['x', 'y', 'z', 'w']
|
|
469
|
-
Vector2: Type.Object({ // },
|
|
470
|
-
x: Type.Number(), // Vector3: {
|
|
471
|
-
y: Type.Number() // type: 'object',
|
|
472
|
-
}) // properties: {
|
|
473
|
-
}, { $id: 'Math3D' }) // x: { 'type': 'number' },
|
|
474
|
-
// y: { 'type': 'number' },
|
|
475
|
-
// z: { 'type': 'number' }
|
|
476
|
-
// },
|
|
477
|
-
// required: ['x', 'y', 'z']
|
|
478
|
-
// },
|
|
479
|
-
// Vector2: {
|
|
480
|
-
// type: 'object',
|
|
481
|
-
// properties: {
|
|
482
|
-
// x: { 'type': 'number' },
|
|
483
|
-
// y: { 'type': 'number' },
|
|
484
|
-
// },
|
|
485
|
-
// required: ['x', 'y']
|
|
486
|
-
// }
|
|
487
|
-
// }
|
|
488
|
-
// }
|
|
489
|
-
|
|
490
|
-
const Vertex = Type.Object({ // const Vertex = {
|
|
491
|
-
position: Type.Ref(Math3D, 'Vector4'), // type: 'object',
|
|
492
|
-
normal: Type.Ref(Math3D, 'Vector3'), // properties: {
|
|
493
|
-
uv: Type.Ref(Math3D, 'Vector2') // position: { $ref: 'Math3D#/$defs/Vector4' },
|
|
494
|
-
}) // normal: { $ref: 'Math3D#/$defs/Vector3' },
|
|
495
|
-
// uv: { $ref: 'Math3D#/$defs/Vector2' }
|
|
496
|
-
// },
|
|
497
|
-
// required: ['position', 'normal', 'uv']
|
|
498
|
-
// }
|
|
499
|
-
```
|
|
500
|
-
|
|
501
|
-
<a name="Recursive-Types"></a>
|
|
502
|
-
|
|
503
|
-
### Recursive Types
|
|
504
|
-
|
|
505
|
-
Recursive types can be created with the `Type.Rec(...)` function. The following creates a `Node` type that contains an array of inner Nodes. Note that due to current restrictions on TypeScript inference, it is not possible for TypeBox to statically infer for recursive types. TypeBox will infer the inner recursive type as `any`.
|
|
506
|
-
|
|
507
|
-
```typescript
|
|
508
|
-
const Node = Type.Rec(Self => Type.Object({ // const Node = {
|
|
509
|
-
id: Type.String(), // $id: 'Node',
|
|
510
|
-
nodes: Type.Array(Self), // $ref: 'Node#/$defs/self',
|
|
511
|
-
}), { $id: 'Node' }) // $defs: {
|
|
512
|
-
// self: {
|
|
513
|
-
// type: 'object',
|
|
514
|
-
// properties: {
|
|
515
|
-
// id: {
|
|
516
|
-
// type: 'string'
|
|
517
|
-
// },
|
|
518
|
-
// nodes: {
|
|
519
|
-
// type: 'array',
|
|
520
|
-
// items: {
|
|
521
|
-
// $ref: 'Node#/$defs/self'
|
|
522
|
-
// }
|
|
523
|
-
// }
|
|
524
|
-
// }
|
|
525
|
-
// }
|
|
526
|
-
// }
|
|
527
|
-
|
|
528
|
-
type Node = Static<typeof Node> // type Node = {
|
|
529
|
-
// id: string
|
|
530
|
-
// nodes: any[]
|
|
531
|
-
// }
|
|
532
|
-
|
|
533
|
-
function visit(node: Node) {
|
|
534
|
-
for(const inner of node.nodes) {
|
|
535
|
-
visit(inner as Node) // Assert inner as Node
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
```
|
|
539
399
|
|
|
540
400
|
<a name="Extended-Types"></a>
|
|
541
401
|
|
|
@@ -549,35 +409,41 @@ In addition to JSON schema types, TypeBox provides several extended types that a
|
|
|
549
409
|
│ │ │ │
|
|
550
410
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
551
411
|
│ const T = Type.Constructor([ │ type T = new ( │ const T = { │
|
|
552
|
-
│
|
|
553
|
-
│
|
|
554
|
-
│ ], Type.Boolean()) │ ) => boolean │
|
|
412
|
+
│ Type.String(), │ arg0: string, │ type: 'constructor' │
|
|
413
|
+
│ Type.Number() │ arg1: number │ arguments: [{ │
|
|
414
|
+
│ ], Type.Boolean()) │ ) => boolean │ type: 'string' │
|
|
555
415
|
│ │ │ }, { │
|
|
556
|
-
│ │ │
|
|
416
|
+
│ │ │ type: 'number' │
|
|
557
417
|
│ │ │ }], │
|
|
558
418
|
│ │ │ returns: { │
|
|
559
|
-
│ │ │
|
|
419
|
+
│ │ │ type: 'boolean' │
|
|
560
420
|
│ │ │ } │
|
|
561
421
|
│ │ │ } │
|
|
562
422
|
│ │ │ │
|
|
563
423
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
564
424
|
│ const T = Type.Function([ │ type T = ( │ const T = { │
|
|
565
|
-
|
|
|
566
|
-
│
|
|
567
|
-
│ ], Type.Boolean()) │ ) => boolean │
|
|
425
|
+
| Type.String(), │ arg0: string, │ type : 'function', │
|
|
426
|
+
│ Type.Number() │ arg1: number │ arguments: [{ │
|
|
427
|
+
│ ], Type.Boolean()) │ ) => boolean │ type: 'string' │
|
|
568
428
|
│ │ │ }, { │
|
|
569
|
-
│ │ │
|
|
429
|
+
│ │ │ type: 'number' │
|
|
570
430
|
│ │ │ }], │
|
|
571
431
|
│ │ │ returns: { │
|
|
572
|
-
│ │ │
|
|
432
|
+
│ │ │ type: 'boolean' │
|
|
573
433
|
│ │ │ } │
|
|
574
434
|
│ │ │ } │
|
|
575
435
|
│ │ │ │
|
|
576
436
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
437
|
+
│ const T = Type.Uint8Array() │ type T = Uint8Array │ const T = { │
|
|
438
|
+
│ │ │ type: 'Uint8Array', │
|
|
439
|
+
│ │ │ specialized: 'Uint8Array' │
|
|
440
|
+
│ │ │ } │
|
|
441
|
+
│ │ │ │
|
|
442
|
+
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
577
443
|
│ const T = Type.Promise( │ type T = Promise<string> │ const T = { │
|
|
578
|
-
│
|
|
444
|
+
│ Type.String() │ │ type: 'promise', │
|
|
579
445
|
│ ) │ │ item: { │
|
|
580
|
-
│ │ │
|
|
446
|
+
│ │ │ type: 'string' │
|
|
581
447
|
│ │ │ } │
|
|
582
448
|
│ │ │ } │
|
|
583
449
|
│ │ │ │
|
|
@@ -588,46 +454,209 @@ In addition to JSON schema types, TypeBox provides several extended types that a
|
|
|
588
454
|
│ │ │ │
|
|
589
455
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
590
456
|
│ const T = Type.Void() │ type T = void │ const T = { │
|
|
591
|
-
│ │ │ type: '
|
|
457
|
+
│ │ │ type: 'null' │
|
|
592
458
|
│ │ │ } │
|
|
593
459
|
│ │ │ │
|
|
594
460
|
└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
|
|
595
461
|
```
|
|
596
462
|
|
|
463
|
+
<a name="Reference-Types"></a>
|
|
464
|
+
|
|
465
|
+
### Reference Types
|
|
466
|
+
|
|
467
|
+
Types can be referenced with `Type.Ref(...)`. To reference a type, the target type must specify an `$id`.
|
|
468
|
+
|
|
469
|
+
```typescript
|
|
470
|
+
const T = Type.String({ $id: 'T' }) // const T = {
|
|
471
|
+
// $id: 'T',
|
|
472
|
+
// type: 'string'
|
|
473
|
+
// }
|
|
474
|
+
|
|
475
|
+
const R = Type.Ref(T) // const R = {
|
|
476
|
+
// $ref: 'T'
|
|
477
|
+
// }
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
<a name="Recursive-Types"></a>
|
|
481
|
+
|
|
482
|
+
### Recursive Types
|
|
483
|
+
|
|
484
|
+
Recursive types can be created with the `Type.Recursive(...)` function.
|
|
485
|
+
|
|
486
|
+
```typescript
|
|
487
|
+
const Node = Type.Recursive(Node => Type.Object({ // const Node = {
|
|
488
|
+
id: Type.String(), // $id: "Node",
|
|
489
|
+
nodes: Type.Array(Node), // type: "object",
|
|
490
|
+
}), { $id: 'Node' }) // properties: {
|
|
491
|
+
// id: {
|
|
492
|
+
// "type": "string"
|
|
493
|
+
// },
|
|
494
|
+
// nodes: {
|
|
495
|
+
// type: "array",
|
|
496
|
+
// items: {
|
|
497
|
+
// $ref: "Node"
|
|
498
|
+
// }
|
|
499
|
+
// }
|
|
500
|
+
// },
|
|
501
|
+
// required: [
|
|
502
|
+
// "id",
|
|
503
|
+
// "nodes"
|
|
504
|
+
// ]
|
|
505
|
+
// }
|
|
506
|
+
|
|
507
|
+
type Node = Static<typeof Node> // type Node = {
|
|
508
|
+
// id: string
|
|
509
|
+
// nodes: ...
|
|
510
|
+
// }
|
|
511
|
+
|
|
512
|
+
function visit(node: Node) {
|
|
513
|
+
for(const inner of node.nodes) {
|
|
514
|
+
visit(inner)
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
<a name="Generic-Types"></a>
|
|
520
|
+
|
|
521
|
+
### Generic Types
|
|
522
|
+
|
|
523
|
+
Generic types can be created using functions. The following creates a generic `Nullable<T>` type.
|
|
524
|
+
|
|
525
|
+
```typescript
|
|
526
|
+
import { Type, Static, TSchema } from '@sinclair/typebox'
|
|
527
|
+
|
|
528
|
+
const Nullable = <T extends TSchema>(type: T) => Type.Union([type, Type.Null()])
|
|
529
|
+
|
|
530
|
+
const T = Nullable(Type.String()) // const T = {
|
|
531
|
+
// anyOf: [{
|
|
532
|
+
// type: 'string'
|
|
533
|
+
// }, {
|
|
534
|
+
// type: 'null'
|
|
535
|
+
// }]
|
|
536
|
+
// }
|
|
537
|
+
|
|
538
|
+
type T = Static<typeof T> // type T = string | null
|
|
539
|
+
|
|
540
|
+
const U = Nullable(Type.Number()) // const U = {
|
|
541
|
+
// anyOf: [{
|
|
542
|
+
// type: 'number'
|
|
543
|
+
// }, {
|
|
544
|
+
// type: 'null'
|
|
545
|
+
// }]
|
|
546
|
+
// }
|
|
547
|
+
|
|
548
|
+
type U = Static<typeof U> // type U = number | null
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
<a name="Unsafe-Types"></a>
|
|
552
|
+
|
|
553
|
+
### Unsafe Types
|
|
554
|
+
|
|
555
|
+
In some cases, you may need schema definitions that are not provided by TypeBox. In these scenarios, it's common to want to define your own schema and static type inference rules. The `Type.Unsafe(...)` function provides this functionality, allowing you to specify both schema representation and a static type to infer. Consider the following which defines a `number` schema, but will infer as a `string`.
|
|
556
|
+
|
|
557
|
+
```typescript
|
|
558
|
+
const T = Type.Unsafe<string>({ type: 'number' }) // const T = {
|
|
559
|
+
// type: 'number'
|
|
560
|
+
// }
|
|
561
|
+
|
|
562
|
+
type T = Static<typeof T> // type T = string
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
The `Type.Unsafe(...)` function can be used with function generics to create custom schema representations for validators requiring specific schema representations. An example of which would be OpenAPI's `nullable` and `string-enum` representations which are not provided by TypeBox by default. The following demonstrates creating these schemas using the `Type.Unsafe(...)` function.
|
|
566
|
+
|
|
567
|
+
```typescript
|
|
568
|
+
import { Type, Static, TSchema } from '@sinclair/typebox'
|
|
569
|
+
|
|
570
|
+
//--------------------------------------------------------------------------------------------
|
|
571
|
+
//
|
|
572
|
+
// Nullable<T>
|
|
573
|
+
//
|
|
574
|
+
//--------------------------------------------------------------------------------------------
|
|
575
|
+
|
|
576
|
+
function Nullable<T extends TSchema>(schema: T) {
|
|
577
|
+
return Type.Unsafe<Static<T> | null>({ ...schema, nullable: true })
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
const T = Nullable(Type.String()) // const T = {
|
|
581
|
+
// type: 'string',
|
|
582
|
+
// nullable: true
|
|
583
|
+
// }
|
|
584
|
+
|
|
585
|
+
type T = Static<typeof T> // type T = string | null
|
|
586
|
+
|
|
587
|
+
//--------------------------------------------------------------------------------------------
|
|
588
|
+
//
|
|
589
|
+
// StringUnion<[...]>
|
|
590
|
+
//
|
|
591
|
+
//--------------------------------------------------------------------------------------------
|
|
592
|
+
|
|
593
|
+
function StringEnum<T extends string[]>(values: [...T]) {
|
|
594
|
+
return Type.Unsafe<T[number]>({ enum: values })
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
const T = StringEnum(['A', 'B', 'C']) // const T = {
|
|
598
|
+
// enum: ['A', 'B', 'C']
|
|
599
|
+
// }
|
|
600
|
+
|
|
601
|
+
type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
|
|
602
|
+
```
|
|
603
|
+
<a name="Values"></a>
|
|
604
|
+
|
|
605
|
+
### Values
|
|
606
|
+
|
|
607
|
+
TypeBox can construct default values for types. TypeBox will create reasonable defaults for any given type, or produce values based on the schemas the `default` value if specified.
|
|
608
|
+
|
|
609
|
+
```typescript
|
|
610
|
+
import { Value } from '@sinclair/typebox/value'
|
|
611
|
+
import { Type } from '@sinclair/typebox'
|
|
612
|
+
|
|
613
|
+
const T = Type.Object({
|
|
614
|
+
x: Type.Number({ default: 1 }),
|
|
615
|
+
y: Type.Number({ default: 2 }),
|
|
616
|
+
z: Type.Number()
|
|
617
|
+
})
|
|
618
|
+
|
|
619
|
+
const V = Value.Create(T) // const V = {
|
|
620
|
+
// x: 1,
|
|
621
|
+
// y: 2,
|
|
622
|
+
// z: 0
|
|
623
|
+
// }
|
|
624
|
+
```
|
|
625
|
+
|
|
597
626
|
<a name="Strict"></a>
|
|
598
627
|
|
|
599
628
|
### Strict
|
|
600
629
|
|
|
601
|
-
TypeBox schemas contain the
|
|
630
|
+
TypeBox schemas contain the `Kind` and `Modifier` symbol properties. These properties are provided to enable runtime type reflection on schemas, as well as helping TypeBox internally compose types. These properties are not strictly valid JSON schema; so in some cases it may be desirable to omit them. TypeBox provides a `Type.Strict()` function that will omit these properties if necessary.
|
|
602
631
|
|
|
603
632
|
```typescript
|
|
604
|
-
const T = Type.Object({
|
|
605
|
-
|
|
606
|
-
})
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
const U = Type.Strict(T)
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
633
|
+
const T = Type.Object({ // const T = {
|
|
634
|
+
name: Type.Optional(Type.String()) // [Kind]: 'Object',
|
|
635
|
+
}) // type: 'object',
|
|
636
|
+
// properties: {
|
|
637
|
+
// name: {
|
|
638
|
+
// [Kind]: 'String',
|
|
639
|
+
// type: 'string',
|
|
640
|
+
// [Modifier]: 'Optional'
|
|
641
|
+
// }
|
|
642
|
+
// }
|
|
643
|
+
// }
|
|
644
|
+
|
|
645
|
+
const U = Type.Strict(T) // const U = {
|
|
646
|
+
// type: 'object',
|
|
647
|
+
// properties: {
|
|
648
|
+
// name: {
|
|
649
|
+
// type: 'string'
|
|
650
|
+
// }
|
|
651
|
+
// }
|
|
652
|
+
// }
|
|
624
653
|
```
|
|
625
654
|
|
|
626
655
|
<a name="Validation"></a>
|
|
627
656
|
|
|
628
657
|
### Validation
|
|
629
658
|
|
|
630
|
-
TypeBox
|
|
659
|
+
TypeBox schemas target JSON Schema draft 6 so any validator capable of draft 6 should be fine. A good library to use for validation in JavaScript environments is [AJV](https://www.npmjs.com/package/ajv). The following example shows setting up AJV 7 to work with TypeBox.
|
|
631
660
|
|
|
632
661
|
```bash
|
|
633
662
|
$ npm install ajv ajv-formats --save
|
|
@@ -636,13 +665,13 @@ $ npm install ajv ajv-formats --save
|
|
|
636
665
|
```typescript
|
|
637
666
|
//--------------------------------------------------------------------------------------------
|
|
638
667
|
//
|
|
639
|
-
// Import
|
|
668
|
+
// Import TypeBox and AJV
|
|
640
669
|
//
|
|
641
670
|
//--------------------------------------------------------------------------------------------
|
|
642
671
|
|
|
643
672
|
import { Type } from '@sinclair/typebox'
|
|
644
673
|
import addFormats from 'ajv-formats'
|
|
645
|
-
import Ajv from 'ajv
|
|
674
|
+
import Ajv from 'ajv'
|
|
646
675
|
|
|
647
676
|
//--------------------------------------------------------------------------------------------
|
|
648
677
|
//
|
|
@@ -651,22 +680,21 @@ import Ajv from 'ajv/dist/2019'
|
|
|
651
680
|
//--------------------------------------------------------------------------------------------
|
|
652
681
|
|
|
653
682
|
const ajv = addFormats(new Ajv({}), [
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
])
|
|
669
|
-
.addKeyword('modifier')
|
|
683
|
+
'date-time',
|
|
684
|
+
'time',
|
|
685
|
+
'date',
|
|
686
|
+
'email',
|
|
687
|
+
'hostname',
|
|
688
|
+
'ipv4',
|
|
689
|
+
'ipv6',
|
|
690
|
+
'uri',
|
|
691
|
+
'uri-reference',
|
|
692
|
+
'uuid',
|
|
693
|
+
'uri-template',
|
|
694
|
+
'json-pointer',
|
|
695
|
+
'relative-json-pointer',
|
|
696
|
+
'regex'
|
|
697
|
+
])
|
|
670
698
|
|
|
671
699
|
//--------------------------------------------------------------------------------------------
|
|
672
700
|
//
|
|
@@ -674,10 +702,10 @@ const ajv = addFormats(new Ajv({}), [
|
|
|
674
702
|
//
|
|
675
703
|
//--------------------------------------------------------------------------------------------
|
|
676
704
|
|
|
677
|
-
const
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
705
|
+
const Vector = Type.Object({
|
|
706
|
+
x: Type.Number(),
|
|
707
|
+
y: Type.Number(),
|
|
708
|
+
z: Type.Number(),
|
|
681
709
|
}, { additionalProperties: false })
|
|
682
710
|
|
|
683
711
|
//--------------------------------------------------------------------------------------------
|
|
@@ -686,54 +714,42 @@ const User = Type.Object({
|
|
|
686
714
|
//
|
|
687
715
|
//--------------------------------------------------------------------------------------------
|
|
688
716
|
|
|
689
|
-
const
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
}) // ->
|
|
717
|
+
const OK = ajv.validate(Vector, {
|
|
718
|
+
x: 1,
|
|
719
|
+
y: 2,
|
|
720
|
+
z: 3
|
|
721
|
+
}) // -> true
|
|
694
722
|
```
|
|
695
723
|
|
|
696
724
|
Please refer to the official AJV [documentation](https://ajv.js.org/guide/getting-started.html) for additional information on using AJV.
|
|
697
725
|
|
|
698
|
-
|
|
726
|
+
<a name="Compiler"></a>
|
|
699
727
|
|
|
700
|
-
|
|
728
|
+
### Compiler
|
|
701
729
|
|
|
702
|
-
|
|
703
|
-
import { Type, Static, TNull, TLiteral, TUnion, TSchema } from '@sinclair/typebox'
|
|
704
|
-
|
|
705
|
-
//--------------------------------------------------------------------------------------------
|
|
706
|
-
//
|
|
707
|
-
// Nullable<T>
|
|
708
|
-
//
|
|
709
|
-
//--------------------------------------------------------------------------------------------
|
|
710
|
-
|
|
711
|
-
function Nullable<T extends TSchema>(schema: T): TUnion<[T, TNull]> {
|
|
712
|
-
return { ...schema, nullable: true } as any
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
const T = Nullable(Type.String()) // const T = {
|
|
716
|
-
// type: 'string',
|
|
717
|
-
// nullable: true
|
|
718
|
-
// }
|
|
719
|
-
|
|
720
|
-
type T = Static<typeof T> // type T = string | null
|
|
730
|
+
TypeBox provides an optional type compiler that can be used as a runtime type checker in absense of a JSON Schema validator. Please note that this compiler is not fully JSON Schema compliant and only permits compilation of TypeBox types only (where the schema representation is known in advance). The `TypeCompiler` contains a `TypeCompiler.Compile(T)` method that returns a `TypeCheck<T>` object that can be used to test the validity of a value.
|
|
721
731
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
732
|
+
```typescript
|
|
733
|
+
import { TypeCompiler } from '@sinclair/typebox/compiler'
|
|
734
|
+
import { Type } from '@sinclair/typebox'
|
|
735
|
+
|
|
736
|
+
const T = Type.Object({
|
|
737
|
+
x: Type.Number(),
|
|
738
|
+
y: Type.Number(),
|
|
739
|
+
z: Type.Number()
|
|
740
|
+
})
|
|
741
|
+
|
|
742
|
+
const C = TypeCompiler.Compile(T)
|
|
743
|
+
|
|
744
|
+
const OK = C.Check({
|
|
745
|
+
x: 1,
|
|
746
|
+
y: 2,
|
|
747
|
+
z: 3
|
|
748
|
+
}) // -> true
|
|
749
|
+
```
|
|
727
750
|
|
|
728
|
-
|
|
751
|
+
<a name="Contribute"></a>
|
|
729
752
|
|
|
730
|
-
|
|
731
|
-
return { enum: values } as any
|
|
732
|
-
}
|
|
753
|
+
### Contribute
|
|
733
754
|
|
|
734
|
-
|
|
735
|
-
// enum: ['A', 'B', 'C']
|
|
736
|
-
// }
|
|
737
|
-
|
|
738
|
-
type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
|
|
739
|
-
```
|
|
755
|
+
TypeBox is open to community contribution, however please ensure you submit an open issue before submitting your pull request. The TypeBox project does preference open community discussion prior to accepting new features.
|