langium-zod / generateZodCode
Function: generateZodCode()
function generateZodCode(
descriptors,
recursiveTypes,
options?): string;Defined in: generator.ts:350
Generates a TypeScript source string containing Zod schema exports for all provided type descriptors.
Emission order is:
- Keyword-enum schemas (
z.literal/z.union([z.literal(...)])) - Regex-enum schemas (
z.string().regex(...)) - Primitive-alias schemas (
z.string(),z.number(), etc.) - Object schemas in topological dependency order; properties that form reference cycles are emitted as getter accessors to avoid forward-reference errors.
- Discriminated-union schemas (all member object schemas are already declared).
- A master
AstNodeSchemadiscriminated union across all object schemas. - Optional cross-reference schema factories when
options.crossRefValidationis enabled.
Parameters
| Parameter | Type | Description |
|---|---|---|
descriptors | ZodTypeDescriptor[] | Full set of type descriptors produced by extractTypeDescriptors. Projection / stripInternals filtering is applied internally via applyProjectionToDescriptors. |
recursiveTypes | Set<string> | Set of type names that participate in a reference cycle, produced by detectRecursiveTypes. These are emitted with getter syntax. |
options | GenerationOptions | Optional flags controlling output style (objectStyle, formMetadata, crossRefValidation, projection, stripInternals). |
Returns
string
The generated TypeScript source as a string (does not write to disk).
Remarks
The generated file includes a // @ts-nocheck comment at the top because the getter-based cycle-breaking syntax is not always accepted by TypeScript's strict object literal type checker. Do not remove it from generated output.
Union schemas are always emitted after all object schemas. Properties that reference a union type use z.lazy() wrappers automatically (tracked via unionNames), so the output is always valid even when object schemas reference unions that are defined later in the file.
This function does not write to disk; call generateZodSchemas to write to config.outputPath.
Example
import { extractTypeDescriptors, detectRecursiveTypes, generateZodCode } from 'langium-zod';
import { collectAst } from 'langium/grammar';
const astTypes = collectAst(myGrammar);
const descriptors = extractTypeDescriptors(astTypes);
const recursiveTypes = detectRecursiveTypes(descriptors);
const source = generateZodCode(descriptors, recursiveTypes, { objectStyle: 'strict' });Use When
- You already have descriptors and a recursion set and want to run code generation in isolation (e.g. for testing the emitter with synthetic descriptors).
- You need to generate code multiple times with different
optionsfrom the same descriptor set without re-running extraction. - You are building a custom pipeline that inserts descriptor transformations between extraction and code generation.
Avoid When
- You are doing a standard end-to-end generation — use generateZodSchemas instead, which orchestrates all pipeline stages and handles disk writes.
- You need
regexOverridesapplied — those are applied by generateZodSchemas before this function is called.
Never
- NEVER pass a
recursiveTypesset that was computed from a different descriptor set thandescriptors. BECAUSE the generator uses the set to decide which properties need getter syntax; a stale set will produceconstdeclarations that reference variables before they are initialised, causing runtime errors. - NEVER rely on emission order outside the documented phases. BECAUSE topological sort is applied only to object descriptors; union and enum schemas appear in their extraction order. Post-processing the string is fragile — transform descriptors before calling this function instead.
- NEVER assume
formMetadata: trueaddsdescriptionto every property. BECAUSEdescriptionis only included when the grammar comment for that property/type is non-empty; title is always emitted viahumanize-string.