Skip to content

langium-zod / extractTypeDescriptors

Function: extractTypeDescriptors()

ts
function extractTypeDescriptors(astTypes, config?): ZodTypeDescriptor[];

Defined in: extractor.ts:408

Extracts ZodTypeDescriptor records from a Langium grammar's type model.

Runs a three-phase pipeline:

  1. Object descriptors — converts each InterfaceType (with inherited properties resolved through the super-type chain) into a ZodObjectTypeDescriptor.
  2. Union / enum descriptors — converts each UnionType into one of: ZodUnionTypeDescriptor (discriminated union of interfaces), ZodKeywordEnumDescriptor (pure keyword literal union), ZodRegexEnumDescriptor (terminal regex ± keyword alternatives), or ZodPrimitiveAliasDescriptor (simple primitive alias such as BigDecimal).
  3. Stub descriptors — synthesises primitive-alias stubs for any referenced type name that does not appear in astTypes (e.g. standalone datatype rules).

Include/exclude filtering from config is applied at each phase.

Parameters

ParameterTypeDescription
astTypesAstTypesLikeThe interface and union types collected from a Langium grammar, typically produced by Langium's collectAst().
config?FilterConfigOptional include/exclude filter controlling which type names are emitted.

Returns

ZodTypeDescriptor[]

A flat array of type descriptors ready for code generation.

Remarks

This function operates on the duck-typed AstTypesLike shape rather than Langium's concrete AstTypes class. You can pass plain object literals in tests without importing from Langium internals.

Properties whose names start with $ (other than $type) are silently skipped — these are Langium bookkeeping fields ($container, $document, etc.) that should not appear in user-facing Zod schemas. Use stripInternals in ZodGeneratorConfig (via generateZodSchemas) to also strip $type from the projection surface.

Each object descriptor always includes a synthetic $type literal property set to the interface's name. This property is the discriminator key for generated discriminated-union schemas.

Throws

ZodGeneratorError when a property's type cannot be mapped to a known Zod schema kind (e.g. an unresolvable terminal reference).

Example

ts
import { extractTypeDescriptors } from 'langium-zod';
import { collectAst } from 'langium/grammar';

const astTypes = collectAst(myGrammar);
const descriptors = extractTypeDescriptors(astTypes, { exclude: ['InternalNode'] });
console.log(descriptors.map(d => d.name));

Use When

  • You want to inspect or transform the intermediate descriptor representation before generating code (e.g. to add custom properties or change types).
  • You are caching descriptors across multiple calls to generateZodCode with different options, so you only want to pay the extraction cost once.
  • You are writing tests against the descriptor model rather than the generated source.

Avoid When

  • You just want generated Zod schemas — use generateZodSchemas instead, which calls this function internally.
  • You want to apply regexOverrides — those are applied in generateZodSchemas after extraction and are not visible in the raw descriptor array.

Never

  • NEVER filter by include without including stub types that are transitively referenced (e.g. ValidID). BECAUSE phase 3 only emits stubs for names that shouldInclude() passes; missing stubs produce undefined schema references at code-gen time.
  • NEVER assume the returned array order matches the grammar declaration order. BECAUSE the array is grouped by phase (object, then union, then stub); use generateZodCode which topologically sorts object schemas.
  • NEVER mutate the returned descriptors and re-pass them to extraction — descriptors are consumed by the generator as values, but the super-type resolution cache lives inside a single extractTypeDescriptors call; mutations do not propagate.
  • NEVER pass a grammar with a union type whose only member is itself filtered out by include. BECAUSE the union will have zero members and produce a broken discriminated union schema.

See

Released under the MIT License.