0
# Compilation
1
2
High-performance validation through schema compilation to optimized JavaScript code. The TypeCompiler generates fast validation functions that significantly outperform standard JSON Schema validators.
3
4
## Capabilities
5
6
### Schema Compilation
7
8
#### Compile Function
9
10
Compiles a schema to an optimized runtime checker.
11
12
```typescript { .api }
13
/**
14
* Compiles schema to optimized runtime checker
15
* @param schema - Schema to compile
16
* @returns TypeCheck instance with validation methods
17
*/
18
function Compile<T extends TSchema>(schema: T, references?: TSchema[]): TypeCheck<T>;
19
20
interface TypeCheck<T extends TSchema> {
21
/** Check if value matches schema */
22
Check(value: unknown): value is Static<T>;
23
/** Get validation errors for value */
24
Errors(value: unknown): ValueErrorIterator;
25
/** Get source code of compiled checker */
26
Code(): string;
27
/** Decode transformed values (for transform schemas) */
28
Decode(value: unknown): StaticDecode<T>;
29
/** Encode values for transformation (for transform schemas) */
30
Encode(value: unknown): StaticEncode<T>;
31
}
32
```
33
34
**Usage Examples:**
35
36
```typescript
37
import { TypeCompiler, Type } from "@sinclair/typebox";
38
39
const User = Type.Object({
40
name: Type.String({ minLength: 2 }),
41
age: Type.Number({ minimum: 0, maximum: 120 }),
42
email: Type.String({ format: 'email' }),
43
isActive: Type.Optional(Type.Boolean())
44
});
45
46
// Compile the schema
47
const userChecker = TypeCompiler.Compile(User);
48
49
// Use compiled checker for validation
50
const userData = { name: "Alice", age: 25, email: "alice@example.com" };
51
52
if (userChecker.Check(userData)) {
53
console.log("Valid user:", userData);
54
// TypeScript knows userData is properly typed here
55
} else {
56
console.log("Invalid user");
57
for (const error of userChecker.Errors(userData)) {
58
console.log(`${error.path}: ${error.message}`);
59
}
60
}
61
```
62
63
#### Code Generation
64
65
Generates validation code as a string for inspection or advanced use cases.
66
67
```typescript { .api }
68
/**
69
* Generates validation code as string
70
* @param schema - Schema to generate code for
71
* @param options - Code generation options
72
* @returns Generated JavaScript code
73
*/
74
function Code<T extends TSchema>(schema: T, references?: TSchema[], options?: TypeCompilerCodegenOptions): string;
75
76
interface TypeCompilerCodegenOptions {
77
/** Function name for generated code (default: 'check') */
78
functionName?: string;
79
/** Include source maps in generated code */
80
sourceMaps?: boolean;
81
/** Optimize for size vs speed */
82
optimize?: 'size' | 'speed';
83
}
84
```
85
86
**Usage Examples:**
87
88
```typescript
89
const User = Type.Object({
90
name: Type.String(),
91
age: Type.Number()
92
});
93
94
// Generate code with default options
95
const defaultCode = TypeCompiler.Code(User);
96
console.log(defaultCode);
97
98
// Generate code with custom function name
99
const namedCode = TypeCompiler.Code(User, {
100
functionName: 'validateUser'
101
});
102
103
// Generated code can be used in dynamic contexts
104
const validateFn = new Function('return ' + namedCode)();
105
const isValid = validateFn({ name: "Alice", age: 25 });
106
```
107
108
### Performance Characteristics
109
110
The compiled validators provide significant performance benefits:
111
112
- **10-100x faster** than standard JSON Schema validators
113
- **Type-specific optimizations** for each schema type
114
- **Minimal memory allocation** during validation
115
- **Branch optimization** for union and conditional types
116
- **Inline validation** without function call overhead
117
118
**Performance Example:**
119
120
```typescript
121
import { TypeCompiler, Value, Type } from "@sinclair/typebox";
122
123
const schema = Type.Object({
124
users: Type.Array(Type.Object({
125
id: Type.String(),
126
name: Type.String(),
127
email: Type.String({ format: 'email' }),
128
age: Type.Number({ minimum: 0, maximum: 120 })
129
}))
130
});
131
132
const compiledChecker = TypeCompiler.Compile(schema);
133
const largeDataset = /* ... thousands of user objects ... */;
134
135
// Compiled validation (fast)
136
console.time('Compiled');
137
for (const item of largeDataset) {
138
compiledChecker.Check(item);
139
}
140
console.timeEnd('Compiled');
141
142
// Standard validation (slower)
143
console.time('Standard');
144
for (const item of largeDataset) {
145
Value.Check(schema, item);
146
}
147
console.timeEnd('Standard');
148
```
149
150
### Advanced Compilation Features
151
152
#### Custom Error Messages
153
154
Compiled checkers provide detailed error information with path and context.
155
156
```typescript { .api }
157
interface ValueErrorIterator {
158
[Symbol.iterator](): IterableIterator<ValueError>;
159
First(): ValueError | undefined;
160
}
161
162
interface ValueError {
163
type: ValueErrorType;
164
schema: TSchema;
165
path: string;
166
value: unknown;
167
message: string;
168
}
169
```
170
171
**Usage Examples:**
172
173
```typescript
174
const schema = Type.Object({
175
nested: Type.Object({
176
items: Type.Array(Type.Number({ minimum: 0 }))
177
})
178
});
179
180
const checker = TypeCompiler.Compile(schema);
181
const invalidData = { nested: { items: [1, -2, 3] } };
182
183
if (!checker.Check(invalidData)) {
184
for (const error of checker.Errors(invalidData)) {
185
console.log(`Path: ${error.path}`);
186
console.log(`Message: ${error.message}`);
187
console.log(`Value: ${JSON.stringify(error.value)}`);
188
}
189
// Output:
190
// Path: /nested/items/1
191
// Message: Expected number to be greater or equal to 0
192
// Value: -2
193
}
194
```
195
196
#### Code Inspection
197
198
Examine the generated validation code for debugging or optimization.
199
200
```typescript
201
const User = Type.Object({
202
name: Type.String({ minLength: 1 }),
203
age: Type.Number({ minimum: 0 })
204
});
205
206
const checker = TypeCompiler.Compile(User);
207
console.log(checker.Code());
208
209
// Generated code example:
210
// function check(value) {
211
// return (
212
// typeof value === 'object' && value !== null &&
213
// typeof value.name === 'string' && value.name.length >= 1 &&
214
// typeof value.age === 'number' && value.age >= 0
215
// );
216
// }
217
```
218
219
### Compilation Limitations
220
221
While TypeCompiler supports most TypeBox schemas, some advanced features have limitations:
222
223
#### Supported Features
224
- All basic types (String, Number, Boolean, Array, Object, etc.)
225
- Union and Intersect types
226
- Literal and Enum types
227
- Most utility types (Partial, Pick, Omit, etc.)
228
- Format validation (email, uuid, date-time, etc.)
229
- Numeric constraints (minimum, maximum, multipleOf)
230
- String constraints (minLength, maxLength, pattern)
231
- Array constraints (minItems, maxItems, uniqueItems)
232
233
#### Limited Support
234
- **Transform types**: Compilation not supported, use Value.Check instead
235
- **Recursive types**: Limited depth compilation
236
- **Custom formats**: Must be registered in FormatRegistry
237
- **Complex conditional logic**: May not optimize effectively
238
239
**Fallback Strategy:**
240
241
```typescript
242
const TransformSchema = Type.Transform(Type.String())
243
.Decode(value => new Date(value))
244
.Encode(value => value.toISOString());
245
246
// Compilation not supported for transforms
247
try {
248
const checker = TypeCompiler.Compile(TransformSchema);
249
} catch (error) {
250
console.log("Compilation failed, using Value.Check");
251
// Fallback to runtime validation
252
const isValid = Value.Check(TransformSchema, someValue);
253
}
254
```
255
256
### Compilation Best Practices
257
258
#### Pre-compile Schemas
259
260
Compile schemas once at startup for optimal performance.
261
262
```typescript
263
// Schema definitions
264
const schemas = {
265
User: Type.Object({
266
name: Type.String(),
267
email: Type.String({ format: 'email' })
268
}),
269
Product: Type.Object({
270
id: Type.String(),
271
price: Type.Number({ minimum: 0 })
272
})
273
};
274
275
// Pre-compile all schemas
276
const checkers = {
277
User: TypeCompiler.Compile(schemas.User),
278
Product: TypeCompiler.Compile(schemas.Product)
279
};
280
281
// Use compiled checkers in request handlers
282
function validateUser(userData: unknown) {
283
return checkers.User.Check(userData);
284
}
285
```
286
287
#### Error Handling Patterns
288
289
```typescript
290
function validateWithErrors<T extends TSchema>(
291
checker: TypeCheck<T>,
292
value: unknown
293
): { valid: boolean; errors: ValueError[] } {
294
if (checker.Check(value)) {
295
return { valid: true, errors: [] };
296
}
297
298
const errors = Array.from(checker.Errors(value));
299
return { valid: false, errors };
300
}
301
302
// Usage
303
const result = validateWithErrors(userChecker, userData);
304
if (!result.valid) {
305
console.log("Validation errors:", result.errors.map(e => e.message));
306
}
307
```
308
309
#### Integration with Frameworks
310
311
```typescript
312
// Express.js middleware example
313
function validateBody<T extends TSchema>(checker: TypeCheck<T>) {
314
return (req: Request, res: Response, next: NextFunction) => {
315
if (checker.Check(req.body)) {
316
next();
317
} else {
318
const errors = Array.from(checker.Errors(req.body));
319
res.status(400).json({
320
error: "Validation failed",
321
details: errors.map(e => ({ path: e.path, message: e.message }))
322
});
323
}
324
};
325
}
326
327
// Usage
328
app.post('/users', validateBody(userChecker), (req, res) => {
329
// req.body is guaranteed to be valid User type
330
const user = req.body as Static<typeof User>;
331
// ... handle request
332
});
333
```
334
335
## Type Interfaces
336
337
```typescript { .api }
338
interface TypeCheck<T extends TSchema> {
339
/** Check if value matches the compiled schema */
340
Check(value: unknown): value is Static<T>;
341
/** Get iterator of validation errors */
342
Errors(value: unknown): ValueErrorIterator;
343
/** Get the generated validation code */
344
Code(): string;
345
}
346
347
interface TypeCompilerCodegenOptions {
348
/** Name for the generated validation function */
349
functionName?: string;
350
/** Include source mapping information */
351
sourceMaps?: boolean;
352
/** Optimization strategy */
353
optimize?: 'size' | 'speed';
354
}
355
356
// Re-exported from errors module
357
interface ValueError {
358
type: ValueErrorType;
359
schema: TSchema;
360
path: string;
361
value: unknown;
362
message: string;
363
}
364
365
interface ValueErrorIterator extends IterableIterator<ValueError> {
366
/** Get the first error without iteration */
367
First(): ValueError | undefined;
368
}
369
```