@sinclair/typebox 0.23.5 → 0.24.0
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 +31 -0
- package/compiler/compiler.js +349 -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 +373 -358
- package/typebox.d.ts +315 -297
- package/typebox.js +247 -263
- 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
|
@@ -34,7 +34,7 @@ import { Static, Type } from 'https://deno.land/x/typebox/src/typebox.ts'
|
|
|
34
34
|
```typescript
|
|
35
35
|
import { Static, Type } from '@sinclair/typebox'
|
|
36
36
|
|
|
37
|
-
const T = Type.String() // const T = {
|
|
37
|
+
const T = Type.String() // const T = { type: 'string' }
|
|
38
38
|
|
|
39
39
|
type T = Static<typeof T> // type T = string
|
|
40
40
|
```
|
|
@@ -43,11 +43,9 @@ type T = Static<typeof T> // type T = string
|
|
|
43
43
|
|
|
44
44
|
## Overview
|
|
45
45
|
|
|
46
|
-
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
|
+
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.
|
|
47
47
|
|
|
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.
|
|
49
|
-
|
|
50
|
-
Requires TypeScript 4.3.5 and above.
|
|
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.
|
|
51
49
|
|
|
52
50
|
License MIT
|
|
53
51
|
|
|
@@ -58,13 +56,16 @@ License MIT
|
|
|
58
56
|
- [Types](#Types)
|
|
59
57
|
- [Modifiers](#Modifiers)
|
|
60
58
|
- [Options](#Options)
|
|
61
|
-
- [
|
|
59
|
+
- [Extended Types](#Extended-Types)
|
|
62
60
|
- [Reference Types](#Reference-Types)
|
|
63
61
|
- [Recursive Types](#Recursive-Types)
|
|
64
|
-
- [
|
|
62
|
+
- [Generic Types](#Generic-Types)
|
|
63
|
+
- [Unsafe Types](#Unsafe-Types)
|
|
64
|
+
- [Values](#Values)
|
|
65
65
|
- [Strict](#Strict)
|
|
66
66
|
- [Validation](#Validation)
|
|
67
|
-
- [
|
|
67
|
+
- [Compiler](#Compiler)
|
|
68
|
+
- [Contribute](#Contribute)
|
|
68
69
|
|
|
69
70
|
<a name="Example"></a>
|
|
70
71
|
|
|
@@ -83,9 +84,9 @@ import { Static, Type } from '@sinclair/typebox'
|
|
|
83
84
|
//--------------------------------------------------------------------------------------------
|
|
84
85
|
|
|
85
86
|
type T = {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
id: string,
|
|
88
|
+
name: string,
|
|
89
|
+
timestamp: number
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
//--------------------------------------------------------------------------------------------
|
|
@@ -94,25 +95,25 @@ type T = {
|
|
|
94
95
|
//
|
|
95
96
|
//--------------------------------------------------------------------------------------------
|
|
96
97
|
|
|
97
|
-
const T = Type.Object({
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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
|
+
// }
|
|
116
117
|
|
|
117
118
|
//--------------------------------------------------------------------------------------------
|
|
118
119
|
//
|
|
@@ -120,11 +121,11 @@ const T = Type.Object({ // const T = {
|
|
|
120
121
|
//
|
|
121
122
|
//--------------------------------------------------------------------------------------------
|
|
122
123
|
|
|
123
|
-
type T = Static<typeof T>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
type T = Static<typeof T> // type T = {
|
|
125
|
+
// id: string,
|
|
126
|
+
// name: string,
|
|
127
|
+
// timestamp: number
|
|
128
|
+
// }
|
|
128
129
|
|
|
129
130
|
//--------------------------------------------------------------------------------------------
|
|
130
131
|
//
|
|
@@ -132,12 +133,11 @@ type T = Static<typeof T> // type T = {
|
|
|
132
133
|
//
|
|
133
134
|
//--------------------------------------------------------------------------------------------
|
|
134
135
|
|
|
135
|
-
function receive(value: T) {
|
|
136
|
-
|
|
137
|
-
if(JSON.validate(T, value)) { // ... as a Schema
|
|
136
|
+
function receive(value: T) { // ... as a Type
|
|
138
137
|
|
|
138
|
+
if(JSON.validate(T, value)) { // ... as a Schema
|
|
139
139
|
// ok...
|
|
140
|
-
|
|
140
|
+
}
|
|
141
141
|
}
|
|
142
142
|
```
|
|
143
143
|
|
|
@@ -159,22 +159,22 @@ The following table outlines the TypeBox mappings between TypeScript and JSON sc
|
|
|
159
159
|
│ │ │ │
|
|
160
160
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
161
161
|
│ const T = Type.String() │ type T = string │ const T = { │
|
|
162
|
-
│ │ │
|
|
162
|
+
│ │ │ type: 'string' │
|
|
163
163
|
│ │ │ } │
|
|
164
164
|
│ │ │ │
|
|
165
165
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
166
166
|
│ const T = Type.Number() │ type T = number │ const T = { │
|
|
167
|
-
│ │ │
|
|
167
|
+
│ │ │ type: 'number' │
|
|
168
168
|
│ │ │ } │
|
|
169
169
|
│ │ │ │
|
|
170
170
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
171
171
|
│ const T = Type.Integer() │ type T = number │ const T = { │
|
|
172
|
-
│ │ │
|
|
172
|
+
│ │ │ type: 'integer' │
|
|
173
173
|
│ │ │ } │
|
|
174
174
|
│ │ │ │
|
|
175
175
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
176
176
|
│ const T = Type.Boolean() │ type T = boolean │ const T = { │
|
|
177
|
-
│ │ │
|
|
177
|
+
│ │ │ type: 'boolean' │
|
|
178
178
|
│ │ │ } │
|
|
179
179
|
│ │ │ │
|
|
180
180
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
@@ -196,16 +196,16 @@ The following table outlines the TypeBox mappings between TypeScript and JSON sc
|
|
|
196
196
|
│ │ │ │
|
|
197
197
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
198
198
|
│ const T = Type.Array( │ type T = number[] │ const T = { │
|
|
199
|
-
│
|
|
200
|
-
│ ) │ │
|
|
201
|
-
│ │ │
|
|
202
|
-
│ │ │
|
|
199
|
+
│ Type.Number() │ │ type: 'array', │
|
|
200
|
+
│ ) │ │ items: { │
|
|
201
|
+
│ │ │ type: 'number' │
|
|
202
|
+
│ │ │ } │
|
|
203
203
|
│ │ │ } │
|
|
204
204
|
│ │ │ │
|
|
205
205
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
206
206
|
│ const T = Type.Object({ │ type T = { │ const T = { │
|
|
207
|
-
│ x: Type.Number(), │
|
|
208
|
-
│ y: Type.Number() │
|
|
207
|
+
│ x: Type.Number(), │ x: number, │ type: 'object', │
|
|
208
|
+
│ y: Type.Number() │ y: number │ properties: { │
|
|
209
209
|
│ }) │ } │ x: { │
|
|
210
210
|
│ │ │ type: 'number' │
|
|
211
211
|
│ │ │ }, │
|
|
@@ -218,19 +218,18 @@ The following table outlines the TypeBox mappings between TypeScript and JSON sc
|
|
|
218
218
|
│ │ │ │
|
|
219
219
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
220
220
|
│ const T = Type.Tuple([ │ type T = [number, number] │ const T = { │
|
|
221
|
-
│ Type.Number(), │ │
|
|
222
|
-
│ Type.Number() │ │
|
|
223
|
-
│ ]) │ │
|
|
224
|
-
│ │ │
|
|
225
|
-
│ │ │
|
|
226
|
-
│ │ │
|
|
227
|
-
│ │ │ } │
|
|
228
|
-
│ │ │ ], │
|
|
221
|
+
│ Type.Number(), │ │ type: 'array', │
|
|
222
|
+
│ Type.Number() │ │ items: [{ │
|
|
223
|
+
│ ]) │ │ type: 'number' │
|
|
224
|
+
│ │ │ }, { │
|
|
225
|
+
│ │ │ type: 'number' │
|
|
226
|
+
│ │ │ }], │
|
|
229
227
|
│ │ │ additionalItems: false, │
|
|
230
228
|
│ │ │ minItems: 2, │
|
|
231
229
|
│ │ │ maxItems: 2, │
|
|
232
230
|
│ │ │ } │
|
|
233
231
|
│ │ │ │
|
|
232
|
+
│ │ │ │
|
|
234
233
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
235
234
|
│ enum Foo { │ enum Foo { │ const T = { │
|
|
236
235
|
│ A, │ A, │ anyOf: [{ │
|
|
@@ -244,85 +243,81 @@ The following table outlines the TypeBox mappings between TypeScript and JSON sc
|
|
|
244
243
|
│ │ │ │
|
|
245
244
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
246
245
|
│ const T = Type.KeyOf( │ type T = keyof { │ const T = { │
|
|
247
|
-
│ Type.Object({ │ x: number, │
|
|
248
|
-
│ x: Type.Number(), │ y: number │
|
|
249
|
-
│ y: Type.Number() │ } │
|
|
250
|
-
│ }) │ │
|
|
251
|
-
│ ) │ │
|
|
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
|
+
│ │ │ } │
|
|
252
254
|
│ │ │ │
|
|
253
255
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
254
256
|
│ const T = Type.Union([ │ type T = string | number │ const T = { │
|
|
255
|
-
│ Type.String(), │ │
|
|
256
|
-
│ Type.Number() │ │
|
|
257
|
-
│ ]) │ │
|
|
258
|
-
│ │ │
|
|
259
|
-
│ │ │
|
|
257
|
+
│ Type.String(), │ │ anyOf: [{ │
|
|
258
|
+
│ Type.Number() │ │ type: 'string' │
|
|
259
|
+
│ ]) │ │ }, { │
|
|
260
|
+
│ │ │ type: 'number' │
|
|
261
|
+
│ │ │ }] │
|
|
260
262
|
│ │ │ } │
|
|
261
263
|
│ │ │ │
|
|
262
264
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
263
265
|
│ const T = Type.Intersect([ │ type T = { │ const T = { │
|
|
264
|
-
│
|
|
265
|
-
│
|
|
266
|
-
│
|
|
267
|
-
│
|
|
268
|
-
│
|
|
269
|
-
│ }) │ │
|
|
270
|
-
│ ]) │ │
|
|
271
|
-
│ │ │
|
|
272
|
-
│ │ │
|
|
273
|
-
│ │ │
|
|
274
|
-
│ │ │ properties: { │
|
|
275
|
-
│ │ │ y: { │
|
|
276
|
-
│ │ │ type: 'number' │
|
|
277
|
-
│ │ │ } │
|
|
278
|
-
│ │ │ }, │
|
|
279
|
-
│ │ │ required: ['y'] │
|
|
280
|
-
│ │ │ }] │
|
|
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'] │
|
|
281
276
|
│ │ │ } │
|
|
282
277
|
│ │ │ │
|
|
283
278
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
284
|
-
│ const T = Type.Record( │ type T =
|
|
285
|
-
│
|
|
286
|
-
│
|
|
287
|
-
│ ) │
|
|
288
|
-
│ │ │
|
|
289
|
-
│ │ │
|
|
290
|
-
│ │ │
|
|
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
|
+
│ │ │ } │
|
|
291
286
|
│ │ │ } │
|
|
292
287
|
│ │ │ │
|
|
293
288
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
294
289
|
│ const T = Type.Partial( │ type T = Partial<{ │ const T = { │
|
|
295
|
-
│
|
|
296
|
-
│
|
|
297
|
-
│
|
|
298
|
-
│
|
|
290
|
+
│ Type.Object({ │ x: number, │ type: 'object', │
|
|
291
|
+
│ x: Type.Number(), │ y: number │ properties: { │
|
|
292
|
+
│ y: Type.Number() | }> │ x: { │
|
|
293
|
+
│ }) │ │ type: 'number' │
|
|
299
294
|
│ ) │ │ }, │
|
|
300
295
|
│ │ │ y: { │
|
|
301
|
-
│ │ │
|
|
296
|
+
│ │ │ type: 'number' │
|
|
302
297
|
│ │ │ } │
|
|
303
298
|
│ │ │ } │
|
|
304
299
|
│ │ │ } │
|
|
305
300
|
│ │ │ │
|
|
306
301
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
307
302
|
│ const T = Type.Required( │ type T = Required<{ │ const T = { │
|
|
308
|
-
│
|
|
309
|
-
│
|
|
310
|
-
│
|
|
311
|
-
│
|
|
312
|
-
│
|
|
313
|
-
│
|
|
314
|
-
│
|
|
315
|
-
│
|
|
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
|
+
│ }) │ │ } │
|
|
316
311
|
│ ) │ │ }, │
|
|
317
312
|
│ │ │ required: ['x', 'y'] │
|
|
318
313
|
│ │ │ } │
|
|
319
314
|
│ │ │ │
|
|
320
315
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
321
316
|
│ const T = Type.Pick( │ type T = Pick<{ │ const T = { │
|
|
322
|
-
│
|
|
323
|
-
│
|
|
324
|
-
│
|
|
325
|
-
│
|
|
317
|
+
│ Type.Object({ │ x: number, │ type: 'object', │
|
|
318
|
+
│ x: Type.Number(), │ y: number │ properties: { │
|
|
319
|
+
│ y: Type.Number(), | }, 'x'> │ x: { │
|
|
320
|
+
│ }), ['x'] │ │ type: 'number' │
|
|
326
321
|
│ ) │ │ } │
|
|
327
322
|
│ │ │ }, │
|
|
328
323
|
│ │ │ required: ['x'] │
|
|
@@ -330,10 +325,10 @@ The following table outlines the TypeBox mappings between TypeScript and JSON sc
|
|
|
330
325
|
│ │ │ │
|
|
331
326
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
332
327
|
│ const T = Type.Omit( │ type T = Omit<{ │ const T = { │
|
|
333
|
-
│
|
|
334
|
-
│
|
|
335
|
-
│
|
|
336
|
-
│
|
|
328
|
+
│ Type.Object({ │ x: number, │ type: 'object', │
|
|
329
|
+
│ x: Type.Number(), │ y: number │ properties: { │
|
|
330
|
+
│ y: Type.Number(), | }, 'x'> │ y: { │
|
|
331
|
+
│ }), ['x'] │ │ type: 'number' │
|
|
337
332
|
│ ) │ │ } │
|
|
338
333
|
│ │ │ }, │
|
|
339
334
|
│ │ │ required: ['y'] │
|
|
@@ -353,8 +348,8 @@ TypeBox provides modifiers that can be applied to an objects properties. This al
|
|
|
353
348
|
│ │ │ │
|
|
354
349
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
355
350
|
│ const T = Type.Object({ │ type T = { │ const T = { │
|
|
356
|
-
│ name: Type.Optional( │
|
|
357
|
-
│
|
|
351
|
+
│ name: Type.Optional( │ name?: string, │ type: 'object', │
|
|
352
|
+
│ Type.String(), │ } │ properties: { │
|
|
358
353
|
│ ) │ │ name: { │
|
|
359
354
|
│ }) │ │ type: 'string' │
|
|
360
355
|
│ │ │ } │
|
|
@@ -363,22 +358,22 @@ TypeBox provides modifiers that can be applied to an objects properties. This al
|
|
|
363
358
|
│ │ │ │
|
|
364
359
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
365
360
|
│ const T = Type.Object({ │ type T = { │ const T = { │
|
|
366
|
-
│ name: Type.Readonly( │
|
|
367
|
-
│
|
|
368
|
-
│ ) │ │
|
|
369
|
-
│ }) │ │
|
|
370
|
-
│ │ │
|
|
361
|
+
│ name: Type.Readonly( │ readonly name: string, │ type: 'object', │
|
|
362
|
+
│ Type.String(), │ } │ properties: { │
|
|
363
|
+
│ ) │ │ name: { │
|
|
364
|
+
│ }) │ │ type: 'string' │
|
|
365
|
+
│ │ │ } │
|
|
371
366
|
│ │ │ }, │
|
|
372
367
|
│ │ │ required: ['name'] │
|
|
373
368
|
│ │ │ } │
|
|
374
369
|
│ │ │ │
|
|
375
370
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
376
371
|
│ const T = Type.Object({ │ type T = { │ const T = { │
|
|
377
|
-
│ name: Type.ReadonlyOptional( │
|
|
378
|
-
│
|
|
379
|
-
│ ) │ │
|
|
380
|
-
│ }) │ │
|
|
381
|
-
│ │ │
|
|
372
|
+
│ name: Type.ReadonlyOptional( │ readonly name?: string │ type: 'object', │
|
|
373
|
+
│ Type.String(), │ } │ properties: { │
|
|
374
|
+
│ ) │ │ name: { │
|
|
375
|
+
│ }) │ │ type: 'string' │
|
|
376
|
+
│ │ │ } │
|
|
382
377
|
│ │ │ } │
|
|
383
378
|
│ │ │ } │
|
|
384
379
|
│ │ │ │
|
|
@@ -401,142 +396,6 @@ const T = Type.Number({ multipleOf: 2 })
|
|
|
401
396
|
// array must have at least 5 integer values
|
|
402
397
|
const T = Type.Array(Type.Integer(), { minItems: 5 })
|
|
403
398
|
```
|
|
404
|
-
<a name="Generic-Types"></a>
|
|
405
|
-
|
|
406
|
-
### Generic Types
|
|
407
|
-
|
|
408
|
-
Generic types can be created using functions. The following creates a generic `Nullable<T>` type.
|
|
409
|
-
|
|
410
|
-
```typescript
|
|
411
|
-
import { Type, Static, TSchema } from '@sinclair/typebox'
|
|
412
|
-
|
|
413
|
-
// type Nullable<T> = T | null
|
|
414
|
-
|
|
415
|
-
const Nullable = <T extends TSchema>(type: T) => Type.Union([type, Type.Null()])
|
|
416
|
-
|
|
417
|
-
const T = Nullable(Type.String()) // const T = {
|
|
418
|
-
// "anyOf": [{
|
|
419
|
-
// type: 'string'
|
|
420
|
-
// }, {
|
|
421
|
-
// type: 'null'
|
|
422
|
-
// }]
|
|
423
|
-
// }
|
|
424
|
-
|
|
425
|
-
type T = Static<typeof T> // type T = string | null
|
|
426
|
-
|
|
427
|
-
const U = Nullable(Type.Number()) // const U = {
|
|
428
|
-
// "anyOf": [{
|
|
429
|
-
// type: 'number'
|
|
430
|
-
// }, {
|
|
431
|
-
// type: 'null'
|
|
432
|
-
// }]
|
|
433
|
-
// }
|
|
434
|
-
|
|
435
|
-
type U = Static<typeof U> // type U = number | null
|
|
436
|
-
```
|
|
437
|
-
|
|
438
|
-
<a name="Reference-Types"></a>
|
|
439
|
-
|
|
440
|
-
### Reference Types
|
|
441
|
-
|
|
442
|
-
Types can be referenced with `Type.Ref(...)`. To reference a type, the target type must specify an `$id`.
|
|
443
|
-
|
|
444
|
-
```typescript
|
|
445
|
-
const T = Type.String({ $id: 'T' }) // const T = {
|
|
446
|
-
// $id: 'T',
|
|
447
|
-
// type: 'string'
|
|
448
|
-
// }
|
|
449
|
-
|
|
450
|
-
const R = Type.Ref(T) // const R = {
|
|
451
|
-
// $ref: 'T'
|
|
452
|
-
// }
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
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.
|
|
456
|
-
|
|
457
|
-
```typescript
|
|
458
|
-
const Math3D = Type.Namespace({ // const Math3D = {
|
|
459
|
-
Vector4: Type.Object({ // $id: 'Math3D',
|
|
460
|
-
x: Type.Number(), // $defs: {
|
|
461
|
-
y: Type.Number(), // Vector4: {
|
|
462
|
-
z: Type.Number(), // type: 'object',
|
|
463
|
-
w: Type.Number() // properties: {
|
|
464
|
-
}), // x: { type: 'number' },
|
|
465
|
-
Vector3: Type.Object({ // y: { type: 'number' },
|
|
466
|
-
x: Type.Number(), // z: { type: 'number' },
|
|
467
|
-
y: Type.Number(), // w: { type: 'number' }
|
|
468
|
-
z: Type.Number() // },
|
|
469
|
-
}), // required: ['x', 'y', 'z', 'w']
|
|
470
|
-
Vector2: Type.Object({ // },
|
|
471
|
-
x: Type.Number(), // Vector3: {
|
|
472
|
-
y: Type.Number() // type: 'object',
|
|
473
|
-
}) // properties: {
|
|
474
|
-
}, { $id: 'Math3D' }) // x: { 'type': 'number' },
|
|
475
|
-
// y: { 'type': 'number' },
|
|
476
|
-
// z: { 'type': 'number' }
|
|
477
|
-
// },
|
|
478
|
-
// required: ['x', 'y', 'z']
|
|
479
|
-
// },
|
|
480
|
-
// Vector2: {
|
|
481
|
-
// type: 'object',
|
|
482
|
-
// properties: {
|
|
483
|
-
// x: { 'type': 'number' },
|
|
484
|
-
// y: { 'type': 'number' },
|
|
485
|
-
// },
|
|
486
|
-
// required: ['x', 'y']
|
|
487
|
-
// }
|
|
488
|
-
// }
|
|
489
|
-
// }
|
|
490
|
-
|
|
491
|
-
const Vertex = Type.Object({ // const Vertex = {
|
|
492
|
-
position: Type.Ref(Math3D, 'Vector4'), // type: 'object',
|
|
493
|
-
normal: Type.Ref(Math3D, 'Vector3'), // properties: {
|
|
494
|
-
uv: Type.Ref(Math3D, 'Vector2') // position: { $ref: 'Math3D#/$defs/Vector4' },
|
|
495
|
-
}) // normal: { $ref: 'Math3D#/$defs/Vector3' },
|
|
496
|
-
// uv: { $ref: 'Math3D#/$defs/Vector2' }
|
|
497
|
-
// },
|
|
498
|
-
// required: ['position', 'normal', 'uv']
|
|
499
|
-
// }
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
<a name="Recursive-Types"></a>
|
|
503
|
-
|
|
504
|
-
### Recursive Types
|
|
505
|
-
|
|
506
|
-
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`.
|
|
507
|
-
|
|
508
|
-
```typescript
|
|
509
|
-
const Node = Type.Rec(Self => Type.Object({ // const Node = {
|
|
510
|
-
id: Type.String(), // $id: 'Node',
|
|
511
|
-
nodes: Type.Array(Self), // $ref: 'Node#/$defs/self',
|
|
512
|
-
}), { $id: 'Node' }) // $defs: {
|
|
513
|
-
// self: {
|
|
514
|
-
// type: 'object',
|
|
515
|
-
// properties: {
|
|
516
|
-
// id: {
|
|
517
|
-
// type: 'string'
|
|
518
|
-
// },
|
|
519
|
-
// nodes: {
|
|
520
|
-
// type: 'array',
|
|
521
|
-
// items: {
|
|
522
|
-
// $ref: 'Node#/$defs/self'
|
|
523
|
-
// }
|
|
524
|
-
// }
|
|
525
|
-
// }
|
|
526
|
-
// }
|
|
527
|
-
// }
|
|
528
|
-
|
|
529
|
-
type Node = Static<typeof Node> // type Node = {
|
|
530
|
-
// id: string
|
|
531
|
-
// nodes: any[]
|
|
532
|
-
// }
|
|
533
|
-
|
|
534
|
-
function visit(node: Node) {
|
|
535
|
-
for(const inner of node.nodes) {
|
|
536
|
-
visit(inner as Node) // Assert inner as Node
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
```
|
|
540
399
|
|
|
541
400
|
<a name="Extended-Types"></a>
|
|
542
401
|
|
|
@@ -550,35 +409,41 @@ In addition to JSON schema types, TypeBox provides several extended types that a
|
|
|
550
409
|
│ │ │ │
|
|
551
410
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
552
411
|
│ const T = Type.Constructor([ │ type T = new ( │ const T = { │
|
|
553
|
-
│
|
|
554
|
-
│
|
|
555
|
-
│ ], Type.Boolean()) │ ) => boolean │
|
|
412
|
+
│ Type.String(), │ arg0: string, │ type: 'constructor' │
|
|
413
|
+
│ Type.Number() │ arg1: number │ arguments: [{ │
|
|
414
|
+
│ ], Type.Boolean()) │ ) => boolean │ type: 'string' │
|
|
556
415
|
│ │ │ }, { │
|
|
557
|
-
│ │ │
|
|
416
|
+
│ │ │ type: 'number' │
|
|
558
417
|
│ │ │ }], │
|
|
559
418
|
│ │ │ returns: { │
|
|
560
|
-
│ │ │
|
|
419
|
+
│ │ │ type: 'boolean' │
|
|
561
420
|
│ │ │ } │
|
|
562
421
|
│ │ │ } │
|
|
563
422
|
│ │ │ │
|
|
564
423
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
565
424
|
│ const T = Type.Function([ │ type T = ( │ const T = { │
|
|
566
|
-
|
|
|
567
|
-
│
|
|
568
|
-
│ ], Type.Boolean()) │ ) => boolean │
|
|
425
|
+
| Type.String(), │ arg0: string, │ type : 'function', │
|
|
426
|
+
│ Type.Number() │ arg1: number │ arguments: [{ │
|
|
427
|
+
│ ], Type.Boolean()) │ ) => boolean │ type: 'string' │
|
|
569
428
|
│ │ │ }, { │
|
|
570
|
-
│ │ │
|
|
429
|
+
│ │ │ type: 'number' │
|
|
571
430
|
│ │ │ }], │
|
|
572
431
|
│ │ │ returns: { │
|
|
573
|
-
│ │ │
|
|
432
|
+
│ │ │ type: 'boolean' │
|
|
574
433
|
│ │ │ } │
|
|
575
434
|
│ │ │ } │
|
|
576
435
|
│ │ │ │
|
|
577
436
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
437
|
+
│ const T = Type.Uint8Array() │ type T = Uint8Array │ const T = { │
|
|
438
|
+
│ │ │ type: 'Uint8Array', │
|
|
439
|
+
│ │ │ specialized: 'Uint8Array' │
|
|
440
|
+
│ │ │ } │
|
|
441
|
+
│ │ │ │
|
|
442
|
+
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
578
443
|
│ const T = Type.Promise( │ type T = Promise<string> │ const T = { │
|
|
579
|
-
│
|
|
444
|
+
│ Type.String() │ │ type: 'promise', │
|
|
580
445
|
│ ) │ │ item: { │
|
|
581
|
-
│ │ │
|
|
446
|
+
│ │ │ type: 'string' │
|
|
582
447
|
│ │ │ } │
|
|
583
448
|
│ │ │ } │
|
|
584
449
|
│ │ │ │
|
|
@@ -589,46 +454,209 @@ In addition to JSON schema types, TypeBox provides several extended types that a
|
|
|
589
454
|
│ │ │ │
|
|
590
455
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
591
456
|
│ const T = Type.Void() │ type T = void │ const T = { │
|
|
592
|
-
│ │ │ type: '
|
|
457
|
+
│ │ │ type: 'null' │
|
|
593
458
|
│ │ │ } │
|
|
594
459
|
│ │ │ │
|
|
595
460
|
└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
|
|
596
461
|
```
|
|
597
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
|
+
|
|
598
626
|
<a name="Strict"></a>
|
|
599
627
|
|
|
600
628
|
### Strict
|
|
601
629
|
|
|
602
|
-
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.
|
|
603
631
|
|
|
604
632
|
```typescript
|
|
605
|
-
const T = Type.Object({
|
|
606
|
-
|
|
607
|
-
})
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
const U = Type.Strict(T)
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
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
|
+
// }
|
|
625
653
|
```
|
|
626
654
|
|
|
627
655
|
<a name="Validation"></a>
|
|
628
656
|
|
|
629
657
|
### Validation
|
|
630
658
|
|
|
631
|
-
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.
|
|
632
660
|
|
|
633
661
|
```bash
|
|
634
662
|
$ npm install ajv ajv-formats --save
|
|
@@ -637,13 +665,13 @@ $ npm install ajv ajv-formats --save
|
|
|
637
665
|
```typescript
|
|
638
666
|
//--------------------------------------------------------------------------------------------
|
|
639
667
|
//
|
|
640
|
-
// Import
|
|
668
|
+
// Import TypeBox and AJV
|
|
641
669
|
//
|
|
642
670
|
//--------------------------------------------------------------------------------------------
|
|
643
671
|
|
|
644
672
|
import { Type } from '@sinclair/typebox'
|
|
645
673
|
import addFormats from 'ajv-formats'
|
|
646
|
-
import Ajv from 'ajv
|
|
674
|
+
import Ajv from 'ajv'
|
|
647
675
|
|
|
648
676
|
//--------------------------------------------------------------------------------------------
|
|
649
677
|
//
|
|
@@ -652,22 +680,21 @@ import Ajv from 'ajv/dist/2019'
|
|
|
652
680
|
//--------------------------------------------------------------------------------------------
|
|
653
681
|
|
|
654
682
|
const ajv = addFormats(new Ajv({}), [
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
])
|
|
670
|
-
.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
|
+
])
|
|
671
698
|
|
|
672
699
|
//--------------------------------------------------------------------------------------------
|
|
673
700
|
//
|
|
@@ -675,10 +702,10 @@ const ajv = addFormats(new Ajv({}), [
|
|
|
675
702
|
//
|
|
676
703
|
//--------------------------------------------------------------------------------------------
|
|
677
704
|
|
|
678
|
-
const
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
705
|
+
const Vector = Type.Object({
|
|
706
|
+
x: Type.Number(),
|
|
707
|
+
y: Type.Number(),
|
|
708
|
+
z: Type.Number(),
|
|
682
709
|
}, { additionalProperties: false })
|
|
683
710
|
|
|
684
711
|
//--------------------------------------------------------------------------------------------
|
|
@@ -687,54 +714,42 @@ const User = Type.Object({
|
|
|
687
714
|
//
|
|
688
715
|
//--------------------------------------------------------------------------------------------
|
|
689
716
|
|
|
690
|
-
const
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
}) // ->
|
|
717
|
+
const OK = ajv.validate(Vector, {
|
|
718
|
+
x: 1,
|
|
719
|
+
y: 2,
|
|
720
|
+
z: 3
|
|
721
|
+
}) // -> true
|
|
695
722
|
```
|
|
696
723
|
|
|
697
724
|
Please refer to the official AJV [documentation](https://ajv.js.org/guide/getting-started.html) for additional information on using AJV.
|
|
698
725
|
|
|
699
|
-
|
|
726
|
+
<a name="Compiler"></a>
|
|
700
727
|
|
|
701
|
-
|
|
728
|
+
### Compiler
|
|
702
729
|
|
|
703
|
-
|
|
704
|
-
import { Type, Static, TNull, TLiteral, TUnion, TSchema } from '@sinclair/typebox'
|
|
705
|
-
|
|
706
|
-
//--------------------------------------------------------------------------------------------
|
|
707
|
-
//
|
|
708
|
-
// Nullable<T>
|
|
709
|
-
//
|
|
710
|
-
//--------------------------------------------------------------------------------------------
|
|
711
|
-
|
|
712
|
-
function Nullable<T extends TSchema>(schema: T): TUnion<[T, TNull]> {
|
|
713
|
-
return { ...schema, nullable: true } as any
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
const T = Nullable(Type.String()) // const T = {
|
|
717
|
-
// type: 'string',
|
|
718
|
-
// nullable: true
|
|
719
|
-
// }
|
|
720
|
-
|
|
721
|
-
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.
|
|
722
731
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
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
|
+
```
|
|
728
750
|
|
|
729
|
-
|
|
751
|
+
<a name="Contribute"></a>
|
|
730
752
|
|
|
731
|
-
|
|
732
|
-
return { enum: values } as any
|
|
733
|
-
}
|
|
753
|
+
### Contribute
|
|
734
754
|
|
|
735
|
-
|
|
736
|
-
// enum: ['A', 'B', 'C']
|
|
737
|
-
// }
|
|
738
|
-
|
|
739
|
-
type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
|
|
740
|
-
```
|
|
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.
|