0
# Advanced Features
1
2
The zod-to-json-schema library provides powerful advanced features for handling complex use cases, including reference resolution, custom parsing logic, post-processing, and error handling capabilities.
3
4
## Reference Resolution System
5
6
The library includes a sophisticated reference resolution system for handling circular references and reused schemas.
7
8
### Reference Strategies
9
10
```typescript { .api }
11
type RefStrategy = "root" | "relative" | "none" | "seen";
12
```
13
14
#### Root References (Default)
15
Uses absolute paths from the document root:
16
17
```typescript
18
zodToJsonSchema(schema, {
19
$refStrategy: "root",
20
basePath: ["#"]
21
})
22
// Produces: { "$ref": "#/definitions/MySchema" }
23
```
24
25
#### Relative References
26
Uses relative paths between schemas:
27
28
```typescript
29
zodToJsonSchema(schema, {
30
$refStrategy: "relative"
31
})
32
// Produces: { "$ref": "1/definitions/MySchema" }
33
```
34
35
#### No References
36
Inlines all schemas without using `$ref`:
37
38
```typescript
39
zodToJsonSchema(schema, {
40
$refStrategy: "none"
41
})
42
// Produces fully inlined schemas
43
```
44
45
#### Seen References
46
Converts previously seen schemas to `any` type to break cycles:
47
48
```typescript
49
zodToJsonSchema(schema, {
50
$refStrategy: "seen"
51
})
52
// Circular references become: {}
53
```
54
55
### Reference Tracking
56
57
```typescript { .api }
58
interface Refs {
59
seen: Map<ZodTypeDef, Seen>;
60
currentPath: string[];
61
propertyPath: string[] | undefined;
62
flags: { hasReferencedOpenAiAnyType: boolean };
63
}
64
65
interface Seen {
66
def: ZodTypeDef;
67
path: string[];
68
jsonSchema: JsonSchema7Type | undefined;
69
}
70
```
71
72
The `Refs` object tracks all processed schemas to handle circular references and enable reuse.
73
74
### Reference Utilities
75
76
```typescript { .api }
77
function getRefs(options?: string | Partial<Options<Targets>>): Refs;
78
79
function getRelativePath(pathA: string[], pathB: string[]): string;
80
```
81
82
## Custom Override System
83
84
Override callbacks allow custom parsing logic for specific schema types.
85
86
### Override Callback
87
88
```typescript { .api }
89
type OverrideCallback = (
90
def: ZodTypeDef,
91
refs: Refs,
92
seen: Seen | undefined,
93
forceResolution?: boolean
94
) => JsonSchema7Type | undefined | typeof ignoreOverride;
95
```
96
97
### Usage Example
98
99
```typescript
100
const customOverride: OverrideCallback = (def, refs, seen, forceResolution) => {
101
// Custom handling for string schemas
102
if (def.typeName === "ZodString") {
103
return {
104
type: "string",
105
format: "custom-format",
106
pattern: "^custom-.*"
107
};
108
}
109
110
// Custom handling for number schemas with specific constraints
111
if (def.typeName === "ZodNumber" && def.checks) {
112
const hasMinMax = def.checks.some((c: any) => c.kind === "min" || c.kind === "max");
113
if (hasMinMax) {
114
return {
115
type: "number",
116
minimum: 0,
117
maximum: 100,
118
multipleOf: 0.01
119
};
120
}
121
}
122
123
// Use default parser for other types
124
return ignoreOverride;
125
};
126
127
const jsonSchema = zodToJsonSchema(schema, {
128
override: customOverride
129
});
130
```
131
132
### Ignore Override Symbol
133
134
```typescript { .api }
135
const ignoreOverride: unique symbol;
136
```
137
138
Return this symbol from override callbacks to use the default parser.
139
140
## Post-Processing System
141
142
Post-processing callbacks allow modification of generated schemas after initial conversion.
143
144
### Post-Process Callback
145
146
```typescript { .api }
147
type PostProcessCallback = (
148
jsonSchema: JsonSchema7Type | undefined,
149
def: ZodTypeDef,
150
refs: Refs
151
) => JsonSchema7Type | undefined;
152
```
153
154
### Built-in Post-Processor
155
156
```typescript { .api }
157
const jsonDescription: PostProcessCallback;
158
```
159
160
Parses JSON from Zod schema descriptions to embed additional JSON Schema properties:
161
162
```typescript
163
const schema = z.string().describe('{"format": "email", "examples": ["user@example.com"]}');
164
165
const jsonSchema = zodToJsonSchema(schema, {
166
postProcess: jsonDescription
167
});
168
// Results in: { type: "string", format: "email", examples: ["user@example.com"] }
169
```
170
171
### Custom Post-Processing
172
173
```typescript
174
const addExamples: PostProcessCallback = (jsonSchema, def, refs) => {
175
if (!jsonSchema) return jsonSchema;
176
177
// Add examples based on schema type
178
if (jsonSchema.type === "string") {
179
return {
180
...jsonSchema,
181
examples: ["example-string"]
182
};
183
}
184
185
if (jsonSchema.type === "number") {
186
return {
187
...jsonSchema,
188
examples: [42]
189
};
190
}
191
192
return jsonSchema;
193
};
194
195
const jsonSchema = zodToJsonSchema(schema, {
196
postProcess: addExamples
197
});
198
```
199
200
## Error Message System
201
202
The library supports custom validation error messages through the error message system.
203
204
### Error Message Types
205
206
```typescript { .api }
207
type ErrorMessages<
208
T extends JsonSchema7TypeUnion | { format: string } | { pattern: string },
209
OmitProperties extends string = ""
210
> = Partial<
211
Omit<{ [key in keyof T]: string }, OmitProperties | "type" | "errorMessages">
212
>;
213
```
214
215
### Error Message Functions
216
217
```typescript { .api }
218
function addErrorMessage<T extends { errorMessage?: ErrorMessages<any> }>(
219
res: T,
220
key: keyof T,
221
errorMessage: string | undefined,
222
refs: Refs
223
): void;
224
225
function setResponseValueAndErrors<
226
Json7Type extends JsonSchema7TypeUnion & { errorMessage?: ErrorMessages<Json7Type> },
227
Key extends keyof Omit<Json7Type, "errorMessage">
228
>(
229
res: Json7Type,
230
key: Key,
231
value: Json7Type[Key],
232
errorMessage: string | undefined,
233
refs: Refs
234
): void;
235
```
236
237
### Usage Example
238
239
```typescript
240
const schema = z.string()
241
.min(5, "String must be at least 5 characters")
242
.max(20, "String must be at most 20 characters")
243
.email("Must be a valid email address");
244
245
const jsonSchema = zodToJsonSchema(schema, {
246
errorMessages: true
247
});
248
249
// Results in schema with errorMessage properties
250
```
251
252
## Core Processing Functions
253
254
### Schema Definition Parser
255
256
```typescript { .api }
257
function parseDef(
258
def: ZodTypeDef,
259
refs: Refs,
260
forceResolution?: boolean
261
): JsonSchema7Type | undefined;
262
```
263
264
Core function that parses Zod type definitions into JSON Schema.
265
266
**Parameters:**
267
- `def`: The Zod type definition to parse
268
- `refs`: Reference tracking object
269
- `forceResolution`: Forces new schema generation even if seen before
270
271
### Parser Selection
272
273
```typescript { .api }
274
function selectParser(
275
def: any,
276
typeName: ZodFirstPartyTypeKind,
277
refs: Refs
278
): JsonSchema7Type | undefined | InnerDefGetter;
279
280
type InnerDefGetter = () => any;
281
```
282
283
Routes to appropriate parser based on Zod schema type. May return a function for lazy evaluation.
284
285
## OpenAI Specific Features
286
287
### OpenAI Any Type Handling
288
289
When using OpenAI target format, the library automatically handles the special any type:
290
291
```typescript
292
const schema = z.any();
293
294
const jsonSchema = zodToJsonSchema(schema, {
295
target: "openAi",
296
openAiAnyTypeName: "CustomAnyType"
297
});
298
299
// Generates recursive any type definition compatible with OpenAI
300
```
301
302
### OpenAI Union Warnings
303
304
The library warns when using union types at the root level with OpenAI target:
305
306
```typescript
307
const unionSchema = z.union([z.string(), z.number()]);
308
309
const jsonSchema = zodToJsonSchema(unionSchema, {
310
target: "openAi"
311
});
312
// Console warning: "OpenAI may not support schemas with unions as roots!"
313
```
314
315
## Performance Optimization
316
317
### Lazy Evaluation
318
319
The library uses lazy evaluation for recursive schemas to optimize performance:
320
321
```typescript
322
// Lazy evaluation for ZodLazy schemas
323
case ZodFirstPartyTypeKind.ZodLazy:
324
return () => (def as any).getter()._def;
325
```
326
327
### Caching and Memoization
328
329
The `seen` map provides automatic memoization of processed schemas:
330
331
```typescript
332
const refs = getRefs(options);
333
// refs.seen automatically caches processed schemas
334
```
335
336
## Advanced Configuration Patterns
337
338
### Multi-Target Conversion
339
340
```typescript
341
const schema = z.object({
342
name: z.string(),
343
age: z.number()
344
});
345
346
const targets: Targets[] = ["jsonSchema7", "openApi3", "openAi"];
347
348
const schemas = targets.map(target => ({
349
target,
350
schema: zodToJsonSchema(schema, { target })
351
}));
352
```
353
354
### Complex Reference Handling
355
356
```typescript
357
const baseSchema = z.object({
358
id: z.string(),
359
name: z.string()
360
});
361
362
const extendedSchema = z.object({
363
base: baseSchema,
364
items: z.array(baseSchema),
365
optional: baseSchema.optional()
366
});
367
368
const jsonSchema = zodToJsonSchema(extendedSchema, {
369
name: "Extended",
370
$refStrategy: "root",
371
definitions: {
372
Base: baseSchema
373
}
374
});
375
```