Skip to content

langium-zod / generateZodCode

Function: generateZodCode()

ts
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:

  1. Keyword-enum schemas (z.literal / z.union([z.literal(...)]))
  2. Regex-enum schemas (z.string().regex(...))
  3. Primitive-alias schemas (z.string(), z.number(), etc.)
  4. Object schemas in topological dependency order; properties that form reference cycles are emitted as getter accessors to avoid forward-reference errors.
  5. Discriminated-union schemas (all member object schemas are already declared).
  6. A master AstNodeSchema discriminated union across all object schemas.
  7. Optional cross-reference schema factories when options.crossRefValidation is enabled.

Parameters

ParameterTypeDescription
descriptorsZodTypeDescriptor[]Full set of type descriptors produced by extractTypeDescriptors. Projection / stripInternals filtering is applied internally via applyProjectionToDescriptors.
recursiveTypesSet<string>Set of type names that participate in a reference cycle, produced by detectRecursiveTypes. These are emitted with getter syntax.
optionsGenerationOptionsOptional 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

ts
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 options from 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 regexOverrides applied — those are applied by generateZodSchemas before this function is called.

Never

  • NEVER pass a recursiveTypes set that was computed from a different descriptor set than descriptors. BECAUSE the generator uses the set to decide which properties need getter syntax; a stale set will produce const declarations 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: true adds description to every property. BECAUSE description is only included when the grammar comment for that property/type is non-empty; title is always emitted via humanize-string.

See

Released under the MIT License.