Thanks to visit codestin.com
Credit goes to github.com

Skip to content

TypeScript 5.9+ causes TS2615 errors in recursive type definitions #5035

@yz89122

Description

@yz89122

Description

When using TypeScript 5.9.2, Zod's recursive type definitions trigger TS2615 errors: "Type of property 'input'/'output' circularly references itself in mapped type". This prevents projects from upgrading to the latest TypeScript version.

Environment

  • Zod version: 4.0.14
  • TypeScript version: 5.9.2
  • Node version: v24.5.0

Error Details

The error occurs in multiple test files when running pnpm test with TypeScript 5.9.2:

Affected Files:

  • src/v4/classic/tests/recursive-types.test.ts (11 tests, 3 failed)
  • src/v4/classic/tests/lazy.test.ts (type errors)
  • src/v4/mini/tests/recursive-types.test.ts (6 tests, 5 failed)

Example Error Messages:

TypeCheckError: Type of property 'output' circularly references itself in mapped type 'Required<$ZodObjectInternals<{ name: ZodString; subcategories: ZodArray<...>; }, $strip>>'.

TypeCheckError: Type of property 'input' circularly references itself in mapped type 'Required<$ZodObjectInternals<{ value: ZodNumber; next: ZodNullable<ZodObject<..., $strip>>; }, $strip>>'.

Root Cause

TypeScript 5.9 introduced stricter detection of circular references through mapped types. The Required<> utility type in Zod's input and output type definitions creates a mapped type transformation that TypeScript 5.9+ no longer allows in circular reference chains.

Current implementation:

export type input<T> = T extends { _zod: { input: any } } ? Required<T["_zod"]>["input"] : unknown;
export type output<T> = T extends { _zod: { output: any } } ? Required<T["_zod"]>["output"] : unknown;

Reproduction

  1. Clone the Zod repository
  2. Install dependencies with pnpm install
  3. Upgrade TypeScript: pnpm add [email protected] -w
  4. Run tests: pnpm test
  5. Observe TS2615 errors in recursive type tests

Workaround

Projects using Zod with recursive schemas that rely on type inference (z.infer<>, z.input<>, or z.output<>) must stay on TypeScript 5.8.x or earlier.

Note: Since z.infer is an alias for z.output, this affects most TypeScript users who use Zod's type inference with recursive schemas.

Example of affected code:

const Category = z.object({
  name: z.string(),
  subcategories: z.array(z.lazy(() => Category))
});

// This will cause TS2615 in TypeScript 5.9+
type Category = z.infer<typeof Category>;  // Uses output type internally
type CategoryInput = z.input<typeof Category>;  // Uses input type

Projects that only use Zod for runtime validation without type inference are not affected.

Related

This issue blocks TypeScript upgrades for projects using Zod with recursive type definitions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions