@sinclair/typebox 0.24.7 → 0.24.10

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.
@@ -1,4 +1,4 @@
1
- import { TypeError } from './errors';
1
+ import { ValueError } from '../value/errors';
2
2
  import * as Types from '../typebox';
3
3
  export declare type CheckFunction = (value: unknown) => boolean;
4
4
  export declare class TypeCheck<T extends Types.TSchema> {
@@ -7,14 +7,15 @@ export declare class TypeCheck<T extends Types.TSchema> {
7
7
  private readonly checkFunc;
8
8
  private readonly code;
9
9
  constructor(schema: T, additional: Types.TSchema[], checkFunc: CheckFunction, code: string);
10
- /** Returns the generated validation code used to validate this type */
10
+ /** Returns the generated validation code used to validate this type. */
11
11
  Code(): string;
12
- /** Returns an iterator for each type error found in this value */
13
- Errors(value: unknown): Generator<TypeError>;
12
+ /** Returns an iterator for each error in this value. */
13
+ Errors(value: unknown): IterableIterator<ValueError>;
14
14
  /** Returns true if the value matches the given type. */
15
15
  Check(value: unknown): value is Types.Static<T>;
16
16
  }
17
+ /** Compiles TypeBox Types for Runtime Type Checking */
17
18
  export declare namespace TypeCompiler {
18
19
  /** Compiles the given type for runtime type checking. This compiler only accepts known TypeBox types non-inclusive of unsafe types. */
19
- function Compile<T extends Types.TSchema>(schema: T, additional?: Types.TSchema[]): TypeCheck<T>;
20
+ function Compile<T extends Types.TSchema>(schema: T, references?: Types.TSchema[]): TypeCheck<T>;
20
21
  }
@@ -28,7 +28,7 @@ THE SOFTWARE.
28
28
  ---------------------------------------------------------------------------*/
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.TypeCompiler = exports.TypeCheck = void 0;
31
- const errors_1 = require("./errors");
31
+ const errors_1 = require("../value/errors");
32
32
  const Types = require("../typebox");
33
33
  // -------------------------------------------------------------------
34
34
  // TypeCheck
@@ -44,13 +44,13 @@ class TypeCheck {
44
44
  this.checkFunc = checkFunc;
45
45
  this.code = code;
46
46
  }
47
- /** Returns the generated validation code used to validate this type */
47
+ /** Returns the generated validation code used to validate this type. */
48
48
  Code() {
49
49
  return this.code;
50
50
  }
51
- /** Returns an iterator for each type error found in this value */
51
+ /** Returns an iterator for each error in this value. */
52
52
  Errors(value) {
53
- return errors_1.TypeErrors.Errors(this.schema, this.additional, value);
53
+ return errors_1.ValueErrors.Errors(this.schema, this.additional, value);
54
54
  }
55
55
  /** Returns true if the value matches the given type. */
56
56
  Check(value) {
@@ -61,70 +61,71 @@ exports.TypeCheck = TypeCheck;
61
61
  // -------------------------------------------------------------------
62
62
  // TypeCompiler
63
63
  // -------------------------------------------------------------------
64
+ /** Compiles TypeBox Types for Runtime Type Checking */
64
65
  var TypeCompiler;
65
66
  (function (TypeCompiler) {
66
67
  // -------------------------------------------------------------------
67
68
  // Schemas
68
69
  // -------------------------------------------------------------------
69
- function* Any(schema, path) {
70
+ function* Any(schema, value) {
70
71
  yield '(true)';
71
72
  }
72
- function* Array(schema, path) {
73
+ function* Array(schema, value) {
73
74
  const expr = [...Visit(schema.items, `value`)].map((condition) => condition).join(' && ');
74
- yield `(Array.isArray(${path}) && ${path}.every(value => ${expr}))`;
75
+ yield `(Array.isArray(${value}) && ${value}.every(value => ${expr}))`;
75
76
  }
76
- function* Boolean(schema, path) {
77
- yield `(typeof ${path} === 'boolean')`;
77
+ function* Boolean(schema, value) {
78
+ yield `(typeof ${value} === 'boolean')`;
78
79
  }
79
- function* Constructor(schema, path) {
80
- yield* Visit(schema.yields, path);
80
+ function* Constructor(schema, value) {
81
+ yield* Visit(schema.returns, value);
81
82
  }
82
- function* Function(schema, path) {
83
- yield `(typeof ${path} === 'function')`;
83
+ function* Function(schema, value) {
84
+ yield `(typeof ${value} === 'function')`;
84
85
  }
85
- function* Integer(schema, path) {
86
- yield `(typeof ${path} === 'number' && Number.isInteger(${path}))`;
86
+ function* Integer(schema, value) {
87
+ yield `(typeof ${value} === 'number' && Number.isInteger(${value}))`;
87
88
  if (schema.multipleOf)
88
- yield `(${path} % ${schema.multipleOf} === 0)`;
89
+ yield `(${value} % ${schema.multipleOf} === 0)`;
89
90
  if (schema.exclusiveMinimum)
90
- yield `(${path} > ${schema.exclusiveMinimum})`;
91
+ yield `(${value} > ${schema.exclusiveMinimum})`;
91
92
  if (schema.exclusiveMaximum)
92
- yield `(${path} < ${schema.exclusiveMaximum})`;
93
+ yield `(${value} < ${schema.exclusiveMaximum})`;
93
94
  if (schema.minimum)
94
- yield `(${path} >= ${schema.minimum})`;
95
+ yield `(${value} >= ${schema.minimum})`;
95
96
  if (schema.maximum)
96
- yield `(${path} <= ${schema.maximum})`;
97
+ yield `(${value} <= ${schema.maximum})`;
97
98
  }
98
- function* Literal(schema, path) {
99
+ function* Literal(schema, value) {
99
100
  if (typeof schema.const === 'string') {
100
- yield `(${path} === '${schema.const}')`;
101
+ yield `(${value} === '${schema.const}')`;
101
102
  }
102
103
  else {
103
- yield `(${path} === ${schema.const})`;
104
+ yield `(${value} === ${schema.const})`;
104
105
  }
105
106
  }
106
- function* Null(schema, path) {
107
- yield `(${path} === null)`;
107
+ function* Null(schema, value) {
108
+ yield `(${value} === null)`;
108
109
  }
109
- function* Number(schema, path) {
110
- yield `(typeof ${path} === 'number')`;
110
+ function* Number(schema, value) {
111
+ yield `(typeof ${value} === 'number')`;
111
112
  if (schema.multipleOf)
112
- yield `(${path} % ${schema.multipleOf} === 0)`;
113
+ yield `(${value} % ${schema.multipleOf} === 0)`;
113
114
  if (schema.exclusiveMinimum)
114
- yield `(${path} > ${schema.exclusiveMinimum})`;
115
+ yield `(${value} > ${schema.exclusiveMinimum})`;
115
116
  if (schema.exclusiveMaximum)
116
- yield `(${path} < ${schema.exclusiveMaximum})`;
117
+ yield `(${value} < ${schema.exclusiveMaximum})`;
117
118
  if (schema.minimum)
118
- yield `(${path} >= ${schema.minimum})`;
119
+ yield `(${value} >= ${schema.minimum})`;
119
120
  if (schema.maximum)
120
- yield `(${path} <= ${schema.maximum})`;
121
+ yield `(${value} <= ${schema.maximum})`;
121
122
  }
122
- function* Object(schema, path) {
123
- yield `(typeof ${path} === 'object' && ${path} !== null && !Array.isArray(${path}))`;
123
+ function* Object(schema, value) {
124
+ yield `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))`;
124
125
  if (schema.minProperties !== undefined)
125
- yield `(Object.keys(${path}).length >= ${schema.minProperties})`;
126
+ yield `(Object.keys(${value}).length >= ${schema.minProperties})`;
126
127
  if (schema.maxProperties !== undefined)
127
- yield `(Object.keys(${path}).length <= ${schema.maxProperties})`;
128
+ yield `(Object.keys(${value}).length <= ${schema.maxProperties})`;
128
129
  const propertyKeys = globalThis.Object.keys(schema.properties);
129
130
  if (schema.additionalProperties === false) {
130
131
  // optimization: If the property key length matches the required keys length
@@ -132,36 +133,36 @@ var TypeCompiler;
132
133
  // of the property key length. This is because exhaustive testing for values
133
134
  // will occur in subsequent property tests.
134
135
  if (schema.required && schema.required.length === propertyKeys.length) {
135
- yield `(Object.keys(${path}).length === ${propertyKeys.length})`;
136
+ yield `(Object.keys(${value}).length === ${propertyKeys.length})`;
136
137
  }
137
138
  else {
138
139
  const keys = `[${propertyKeys.map((key) => `'${key}'`).join(', ')}]`;
139
- yield `(Object.keys(${path}).every(key => ${keys}.includes(key)))`;
140
+ yield `(Object.keys(${value}).every(key => ${keys}.includes(key)))`;
140
141
  }
141
142
  }
142
143
  for (const propertyKey of propertyKeys) {
143
144
  const propertySchema = schema.properties[propertyKey];
144
145
  if (schema.required && schema.required.includes(propertyKey)) {
145
- yield* Visit(propertySchema, `${path}.${propertyKey}`);
146
+ yield* Visit(propertySchema, `${value}.${propertyKey}`);
146
147
  }
147
148
  else {
148
- const expr = [...Visit(propertySchema, `${path}.${propertyKey}`)].map((condition) => condition).join(' && ');
149
- yield `(${path}.${propertyKey} === undefined ? true : (${expr}))`;
149
+ const expr = [...Visit(propertySchema, `${value}.${propertyKey}`)].map((condition) => condition).join(' && ');
150
+ yield `(${value}.${propertyKey} === undefined ? true : (${expr}))`;
150
151
  }
151
152
  }
152
153
  }
153
- function* Promise(schema, path) {
154
- yield `(typeof value === 'object' && typeof ${path}.then === 'function')`;
154
+ function* Promise(schema, value) {
155
+ yield `(typeof value === 'object' && typeof ${value}.then === 'function')`;
155
156
  }
156
- function* Record(schema, path) {
157
- yield `(typeof ${path} === 'object' && ${path} !== null && !Array.isArray(${path}))`;
157
+ function* Record(schema, value) {
158
+ yield `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))`;
158
159
  const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
159
160
  const local = PushLocal(`const local = new RegExp(/${keyPattern}/)`);
160
- yield `(Object.keys(${path}).every(key => ${local}.test(key)))`;
161
+ yield `(Object.keys(${value}).every(key => ${local}.test(key)))`;
161
162
  const expr = [...Visit(valueSchema, 'value')].map((condition) => condition).join(' && ');
162
- yield `(Object.values(${path}).every(value => ${expr}))`;
163
+ yield `(Object.values(${value}).every(value => ${expr}))`;
163
164
  }
164
- function* Ref(schema, path) {
165
+ function* Ref(schema, value) {
165
166
  // reference: referenced schemas can originate from either additional
166
167
  // schemas or inline in the schema itself. Ideally the recursive
167
168
  // path should align to reference path. Consider for review.
@@ -174,50 +175,56 @@ var TypeCompiler;
174
175
  PushLocal(body);
175
176
  }
176
177
  const func = CreateFunctionName(schema.$ref);
177
- yield `(${func}(${path}))`;
178
+ yield `(${func}(${value}))`;
178
179
  }
179
- function* Self(schema, path) {
180
+ function* Self(schema, value) {
180
181
  const func = CreateFunctionName(schema.$ref);
181
- yield `(${func}(${path}))`;
182
+ yield `(${func}(${value}))`;
182
183
  }
183
- function* String(schema, path) {
184
- yield `(typeof ${path} === 'string')`;
184
+ function* String(schema, value) {
185
+ yield `(typeof ${value} === 'string')`;
186
+ if (schema.minLength !== undefined) {
187
+ yield `(${value}.length >= ${schema.minLength})`;
188
+ }
189
+ if (schema.maxLength !== undefined) {
190
+ yield `(${value}.length <= ${schema.maxLength})`;
191
+ }
185
192
  if (schema.pattern !== undefined) {
186
193
  const local = PushLocal(`const local = new RegExp('${schema.pattern}');`);
187
- yield `(${local}.test(${path}))`;
194
+ yield `(${local}.test(${value}))`;
188
195
  }
189
196
  }
190
- function* Tuple(schema, path) {
191
- yield `(Array.isArray(${path}))`;
197
+ function* Tuple(schema, value) {
198
+ yield `(Array.isArray(${value}))`;
192
199
  if (schema.items === undefined)
193
- return yield `(${path}.length === 0)`;
194
- yield `(${path}.length === ${schema.maxItems})`;
200
+ return yield `(${value}.length === 0)`;
201
+ yield `(${value}.length === ${schema.maxItems})`;
195
202
  for (let i = 0; i < schema.items.length; i++) {
196
- const expr = [...Visit(schema.items[i], `${path}[${i}]`)].map((condition) => condition).join(' && ');
203
+ const expr = [...Visit(schema.items[i], `${value}[${i}]`)].map((condition) => condition).join(' && ');
197
204
  yield `(${expr})`;
198
205
  }
199
206
  }
200
- function* Undefined(schema, path) {
201
- yield `${path} === undefined`;
207
+ function* Undefined(schema, value) {
208
+ yield `(${value} === undefined)`;
202
209
  }
203
- function* Union(schema, path) {
204
- const exprs = schema.anyOf.map((schema) => [...Visit(schema, path)].map((condition) => condition).join(' && '));
210
+ function* Union(schema, value) {
211
+ const exprs = schema.anyOf.map((schema) => [...Visit(schema, value)].map((condition) => condition).join(' && '));
205
212
  yield `(${exprs.join(' || ')})`;
206
213
  }
207
- function* Uint8Array(schema, path) {
208
- yield `(${path} instanceof Uint8Array)`;
214
+ function* Uint8Array(schema, value) {
215
+ yield `(${value} instanceof Uint8Array)`;
209
216
  if (schema.maxByteLength)
210
- yield `(${path}.length <= ${schema.maxByteLength})`;
217
+ yield `(${value}.length <= ${schema.maxByteLength})`;
211
218
  if (schema.minByteLength)
212
- yield `(${path}.length >= ${schema.minByteLength})`;
219
+ yield `(${value}.length >= ${schema.minByteLength})`;
213
220
  }
214
- function* Unknown(schema, path) {
221
+ function* Unknown(schema, value) {
215
222
  yield '(true)';
216
223
  }
217
- function* Void(schema, path) {
218
- yield `(${path} === null)`;
224
+ function* Void(schema, value) {
225
+ yield `(${value} === null)`;
219
226
  }
220
- function* Visit(schema, path) {
227
+ function* Visit(schema, value) {
221
228
  // reference: referenced schemas can originate from either additional
222
229
  // schemas or inline in the schema itself. Ideally the recursive
223
230
  // path should align to reference path. Consider for review.
@@ -227,55 +234,55 @@ var TypeCompiler;
227
234
  const name = CreateFunctionName(schema.$id);
228
235
  const body = CreateFunction(name, conditions);
229
236
  PushLocal(body);
230
- yield `(${name}(${path}))`;
237
+ yield `(${name}(${value}))`;
231
238
  return;
232
239
  }
233
240
  const anySchema = schema;
234
241
  switch (anySchema[Types.Kind]) {
235
242
  case 'Any':
236
- return yield* Any(anySchema, path);
243
+ return yield* Any(anySchema, value);
237
244
  case 'Array':
238
- return yield* Array(anySchema, path);
245
+ return yield* Array(anySchema, value);
239
246
  case 'Boolean':
240
- return yield* Boolean(anySchema, path);
247
+ return yield* Boolean(anySchema, value);
241
248
  case 'Constructor':
242
- return yield* Constructor(anySchema, path);
249
+ return yield* Constructor(anySchema, value);
243
250
  case 'Function':
244
- return yield* Function(anySchema, path);
251
+ return yield* Function(anySchema, value);
245
252
  case 'Integer':
246
- return yield* Integer(anySchema, path);
253
+ return yield* Integer(anySchema, value);
247
254
  case 'Literal':
248
- return yield* Literal(anySchema, path);
255
+ return yield* Literal(anySchema, value);
249
256
  case 'Null':
250
- return yield* Null(anySchema, path);
257
+ return yield* Null(anySchema, value);
251
258
  case 'Number':
252
- return yield* Number(anySchema, path);
259
+ return yield* Number(anySchema, value);
253
260
  case 'Object':
254
- return yield* Object(anySchema, path);
261
+ return yield* Object(anySchema, value);
255
262
  case 'Promise':
256
- return yield* Promise(anySchema, path);
263
+ return yield* Promise(anySchema, value);
257
264
  case 'Record':
258
- return yield* Record(anySchema, path);
265
+ return yield* Record(anySchema, value);
259
266
  case 'Ref':
260
- return yield* Ref(anySchema, path);
267
+ return yield* Ref(anySchema, value);
261
268
  case 'Self':
262
- return yield* Self(anySchema, path);
269
+ return yield* Self(anySchema, value);
263
270
  case 'String':
264
- return yield* String(anySchema, path);
271
+ return yield* String(anySchema, value);
265
272
  case 'Tuple':
266
- return yield* Tuple(anySchema, path);
273
+ return yield* Tuple(anySchema, value);
267
274
  case 'Undefined':
268
- return yield* Undefined(anySchema, path);
275
+ return yield* Undefined(anySchema, value);
269
276
  case 'Union':
270
- return yield* Union(anySchema, path);
277
+ return yield* Union(anySchema, value);
271
278
  case 'Uint8Array':
272
- return yield* Uint8Array(anySchema, path);
279
+ return yield* Uint8Array(anySchema, value);
273
280
  case 'Unknown':
274
- return yield* Unknown(anySchema, path);
281
+ return yield* Unknown(anySchema, value);
275
282
  case 'Void':
276
- return yield* Void(anySchema, path);
283
+ return yield* Void(anySchema, value);
277
284
  default:
278
- throw Error(`Unknown schema kind '${schema[Types.Kind]}'`);
285
+ throw new Error(`TypeCompiler: Unknown schema kind '${schema[Types.Kind]}'`);
279
286
  }
280
287
  }
281
288
  // -------------------------------------------------------------------
@@ -292,9 +299,9 @@ var TypeCompiler;
292
299
  function PushReferences(schemas = []) {
293
300
  for (const schema of schemas) {
294
301
  if (!schema.$id)
295
- throw Error(`Referenced schemas must specify an $id. Failed for '${JSON.stringify(schema)}'`);
302
+ throw new Error(`TypeCompiler: Referenced schemas must specify an $id.`);
296
303
  if (referenceMap.has(schema.$id))
297
- throw Error(`Duplicate schema $id detected for '${schema.$id}'`);
304
+ throw new Error(`TypeCompiler: Duplicate schema $id found for '${schema.$id}'`);
298
305
  referenceMap.set(schema.$id, schema);
299
306
  }
300
307
  }
@@ -319,18 +326,18 @@ var TypeCompiler;
319
326
  // -------------------------------------------------------------------
320
327
  // Compile
321
328
  // -------------------------------------------------------------------
322
- function Build(schema, additional = []) {
329
+ function Build(schema, references = []) {
323
330
  ClearLocals();
324
- PushReferences(additional);
331
+ PushReferences(references);
325
332
  const conditions = [...Visit(schema, 'value')]; // locals populated during yield
326
333
  const locals = GetLocals();
327
334
  return `${locals.join('\n')}\nreturn ${CreateFunction('check', conditions)}`;
328
335
  }
329
336
  /** Compiles the given type for runtime type checking. This compiler only accepts known TypeBox types non-inclusive of unsafe types. */
330
- function Compile(schema, additional = []) {
331
- const code = Build(schema, additional);
337
+ function Compile(schema, references = []) {
338
+ const code = Build(schema, references);
332
339
  const func = globalThis.Function(code);
333
- return new TypeCheck(schema, additional, func(), code);
340
+ return new TypeCheck(schema, references, func(), code);
334
341
  }
335
342
  TypeCompiler.Compile = Compile;
336
343
  })(TypeCompiler = exports.TypeCompiler || (exports.TypeCompiler = {}));
@@ -1,2 +1,2 @@
1
+ export type { ValueError } from '../value/errors';
1
2
  export * from './compiler';
2
- export * from './errors';
package/compiler/index.js CHANGED
@@ -38,4 +38,3 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
38
38
  };
39
39
  Object.defineProperty(exports, "__esModule", { value: true });
40
40
  __exportStar(require("./compiler"), exports);
41
- __exportStar(require("./errors"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.24.7",
3
+ "version": "0.24.10",
4
4
  "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "json-schema",
package/readme.md CHANGED
@@ -450,7 +450,7 @@ In addition to JSON schema types, TypeBox provides several extended types that a
450
450
  │ │ │ │
451
451
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
452
452
  │ const T = Type.Undefined() │ type T = undefined │ const T = { │
453
- │ │ │ type: 'object'
453
+ │ │ │ type: 'object',
454
454
  │ │ │ specialized: 'Undefined' │
455
455
  │ │ │ } │
456
456
  │ │ │ │
@@ -554,7 +554,7 @@ type U = Static<typeof U> // type U = number | null
554
554
 
555
555
  ### Unsafe Types
556
556
 
557
- 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`.
557
+ In some scenarios, you may need specific schemas not provided by TypeBox. In these cases, it's common to want to define a custom schema with custom static inference rules. The `Type.Unsafe(...)` function provides this functionality. This function enables one to specify both schema representation and a static type to infer. Consider the following which defines a `number` schema but infers as `string`.
558
558
 
559
559
  ```typescript
560
560
  const T = Type.Unsafe<string>({ type: 'number' }) // const T = {
@@ -564,7 +564,7 @@ const T = Type.Unsafe<string>({ type: 'number' }) // const T = {
564
564
  type T = Static<typeof T> // type T = string
565
565
  ```
566
566
 
567
- 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.
567
+ The `Type.Unsafe(...)` function can be combined with function generics to create user defined schemas for validators that need specific schema representations. An example of this might be the OpenAPI `nullable` and `string-enum` schema representations which are not provided by TypeBox. The following demonstrates creating these schemas using the `Type.Unsafe(...)` function.
568
568
 
569
569
  ```typescript
570
570
  import { Type, Static, TSchema } from '@sinclair/typebox'
@@ -607,36 +607,51 @@ type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
607
607
 
608
608
  ### Values
609
609
 
610
- 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.
610
+ TypeBox can create values from types. It creates reasonable defaults for each value which can overrided by specifying a `default` value.
611
611
 
612
612
  ```typescript
613
613
  import { Value } from '@sinclair/typebox/value'
614
- import { Type } from '@sinclair/typebox'
614
+ import { Type } from '@sinclair/typebox'
615
615
 
616
616
  const T = Type.Object({
617
617
  x: Type.Number({ default: 1 }),
618
- y: Type.Number({ default: 2 }),
619
- z: Type.Number()
618
+ y: Type.Number(),
620
619
  })
621
620
 
622
621
  const V = Value.Create(T) // const V = {
623
622
  // x: 1,
624
- // y: 2,
625
- // z: 0
623
+ // y: 0,
626
624
  // }
627
625
  ```
626
+ TypeBox also allows values to be upgraded to match the schematics of a given type. The `Value.Cast(...)` function can be used to upgrade a value into a target type while retaining as much information of the original value as possible. Casts are immutable operations.
627
+
628
+ ```typescript
629
+ import { Value } from '@sinclair/typebox/value'
630
+ import { Type } from '@sinclair/typebox'
631
+
632
+ const T = Type.Object({
633
+ x: Type.Number(),
634
+ y: Type.Number()
635
+ })
636
+
637
+ const A = Value.Cast(T, null) // const A = { x: 0, y: 0 }
638
+
639
+ const B = Value.Cast(T, { x: 1 }) // const B = { x: 1, y: 0 }
640
+
641
+ const C = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const C = { x: 1, y: 2 }
642
+ ```
628
643
 
629
644
  <a name="Guards"></a>
630
645
 
631
646
  ### Guards
632
647
 
633
- In some scenarios it may be helpful to test if an object is a valid TypeBox type. You can use the TypeGuard module to check an object conforms to a valid TypeBox schema representation. Consider the following.
648
+ If reflecting on TypeBox types, it can be helpful to test if a value matches a TypeBox schematic. This can be achieved using the TypeGuard namespace. The TypeGuard namespace offers exhaustive checks for each known TypeBox type.
634
649
 
635
650
  ```typescript
636
651
  import { TypeGuard } from '@sinclair/typebox/guard'
637
652
  import { Type } from '@sinclair/typebox'
638
653
 
639
- const T: any = Type.String() // T is any
654
+ const T: any = {} // T is any
640
655
 
641
656
  const { type } = T // unsafe: type is any
642
657
 
@@ -647,8 +662,6 @@ if(TypeGuard.TString(T)) {
647
662
 
648
663
  ```
649
664
 
650
-
651
-
652
665
  <a name="Strict"></a>
653
666
 
654
667
  ### Strict
@@ -728,7 +741,7 @@ const ajv = addFormats(new Ajv({}), [
728
741
  //
729
742
  //--------------------------------------------------------------------------------------------
730
743
 
731
- const Vector = Type.Object({
744
+ const T = Type.Object({
732
745
  x: Type.Number(),
733
746
  y: Type.Number(),
734
747
  z: Type.Number(),
@@ -740,7 +753,7 @@ const Vector = Type.Object({
740
753
  //
741
754
  //--------------------------------------------------------------------------------------------
742
755
 
743
- const OK = ajv.validate(Vector, {
756
+ const OK = ajv.validate(T, {
744
757
  x: 1,
745
758
  y: 2,
746
759
  z: 3
@@ -753,7 +766,7 @@ Please refer to the official AJV [documentation](https://ajv.js.org/guide/gettin
753
766
 
754
767
  ### Compiler
755
768
 
756
- TypeBox includes a specialized type compiler that can be used as a runtime type checker in absense of a JSON Schema validator. This compiler is optimized for high throughput validation scenarios and generally performs better than AJV for most structural checks. Please note that this compiler is not fully JSON Schema compliant and is limited to TypeBox types only. The `TypeCompiler` contains a `Compile(T)` function that returns a `TypeCheck<T>` object that can be used to test the validity of a value as well as obtain errors.
769
+ TypeBox includes a specialized `TypeCompiler` that can be used as a runtime type checker in lieu of a JSON Schema validator. This compiler is optimized for high throughput Web Socket messaging and can perform better than AJV for some structural checks. Please note that this compiler is not fully JSON Schema compliant and is limited to known TypeBox types only. The `TypeCompiler` contains a `Compile(T)` function that returns a `TypeCheck<T>` object that can be used to test the validity of a value as well as obtain errors.
757
770
 
758
771
  ```typescript
759
772
  import { TypeCompiler } from '@sinclair/typebox/compiler'
@@ -773,7 +786,7 @@ const OK = C.Check({
773
786
  z: 3
774
787
  }) // -> true
775
788
  ```
776
- Errors can be obtained by calling the `Errors(...)` function. This function returns an iterator that may contain zero or more errors for the given value. For performance, you should only call `Errors(V)` if the `Check(V)` function returns false.
789
+ Errors can be obtained by calling the `Errors(...)` function. This function returns an iterator that may contain zero or more errors for the given value. For performance, you should only call `Errors(V)` if the `Check(V)` function returns `false`.
777
790
  ```typescript
778
791
  const C = TypeCompiler.Compile(Type.Object({
779
792
  x: Type.Number(),
@@ -789,7 +802,7 @@ if(!C.Check(V)) {
789
802
  }
790
803
  }
791
804
  ```
792
- To inspect the generated validation code created by the compiler. You can call the `Code()` function on the `TypeCheck<T>` object.
805
+ The TypeCompiler generates JavaScript validation routines types that are evaluated at runtime. You can inspect the generated code by calling the `Code()` function of the `TypeCheck<T>` object.
793
806
 
794
807
  ```typescript
795
808
  const C = TypeCompiler.Compile(Type.String())
@@ -809,4 +822,4 @@ console.log(C.Code())
809
822
 
810
823
  ### Contribute
811
824
 
812
- 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.
825
+ TypeBox is open to community contribution. Please ensure you submit an open issue before submitting your pull request. The TypeBox project preferences open community discussion prior to accepting new features.
package/typebox.d.ts CHANGED
@@ -22,12 +22,10 @@ export interface SchemaOptions {
22
22
  title?: string;
23
23
  /** Description of this schema */
24
24
  description?: string;
25
- /** Default value hint for this schema */
25
+ /** Default value for this schema */
26
26
  default?: any;
27
27
  /** Example values matching this schema. */
28
28
  examples?: any;
29
- /** Design metadata for this schema */
30
- design?: DesignType;
31
29
  [prop: string]: any;
32
30
  }
33
31
  export interface TSchema extends SchemaOptions {
package/typebox.js CHANGED
@@ -227,7 +227,7 @@ class TypeBuilder {
227
227
  /** Creates a reference schema */
228
228
  Ref(schema, options = {}) {
229
229
  if (schema.$id === undefined)
230
- throw Error('Cannot create reference schema as target schema as has no $id');
230
+ throw Error('Type.Ref: Referenced schema must specify an $id');
231
231
  return this.Create({ ...options, [exports.Kind]: 'Ref', $ref: schema.$id });
232
232
  }
233
233
  /** Creates a string type from a regular expression */
@@ -0,0 +1,5 @@
1
+ import * as Types from '../typebox';
2
+ export declare namespace ValueCast {
3
+ function Visit(schema: Types.TSchema, references: Types.TSchema[], value: any): any;
4
+ function Cast<T extends Types.TSchema, R extends Types.TSchema[]>(schema: T, references: [...R], value: any): Types.Static<T>;
5
+ }