{"id":12783,"library":"zod-to-ts","title":"Zod to TypeScript Type Generator","description":"zod-to-ts generates TypeScript type definitions directly from Zod schemas, converting Zod's runtime validation objects into static TypeScript types. The current stable version is `2.0.0`, with recent releases focusing on supporting Zod v4 and improving the handling of complex type structures, especially recursion. Releases appear to be feature-driven, with new minor versions adding capabilities and major versions introducing breaking changes, particularly around Zod compatibility and internal API improvements. Key differentiators include its ability to generate TypeScript AST nodes directly for programmatic manipulation, robust support for recursive types through an auxiliary type system, and configurable output (e.g., 'input' vs. 'output' types for schemas using transformations or pipes). It also supports JSDoc comments from Zod's `.describe()` method, making generated types more descriptive. This library is crucial for projects aiming to maintain type safety and reduce boilerplate by deriving types directly from Zod validation logic.","status":"active","version":"2.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/sachinraja/zod-to-ts","tags":["javascript","zod","typescript","generator"],"install":[{"cmd":"npm install zod-to-ts","lang":"bash","label":"npm"},{"cmd":"yarn add zod-to-ts","lang":"bash","label":"yarn"},{"cmd":"pnpm add zod-to-ts","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for TypeScript AST manipulation and type generation. It is a peer dependency.","package":"typescript","optional":false},{"reason":"Core dependency for defining schemas. It is a peer dependency, but v2.x of `zod-to-ts` strictly requires Zod v4+ at runtime.","package":"zod","optional":false}],"imports":[{"note":"This package is primarily designed for ESM usage. While CommonJS `require` might work with some bundler configurations, ESM `import` is the recommended and best-supported approach.","wrong":"const { zodToTs } = require('zod-to-ts')","symbol":"zodToTs","correct":"import { zodToTs } from 'zod-to-ts'"},{"note":"Essential for correctly generating types for recursive Zod schemas, which often require helper types.","wrong":"const { createAuxiliaryTypeStore } = require('zod-to-ts')","symbol":"createAuxiliaryTypeStore","correct":"import { createAuxiliaryTypeStore } from 'zod-to-ts'"},{"note":"Utility to wrap a raw TypeScript AST node into a full `type` alias declaration, making it easier to print.","wrong":"const { createTypeAlias } = require('zod-to-ts')","symbol":"createTypeAlias","correct":"import { createTypeAlias } from 'zod-to-ts'"},{"note":"Used to convert any TypeScript AST node (including those returned by `zodToTs` or `createTypeAlias`) into its string representation.","wrong":"const { printNode } = require('zod-to-ts')","symbol":"printNode","correct":"import { printNode } from 'zod-to-ts'"}],"quickstart":{"code":"import { z } from 'zod';\nimport { zodToTs, createAuxiliaryTypeStore, createTypeAlias, printNode } from 'zod-to-ts';\n\nconst CategorySchema = z.object({\n  name: z.string(),\n  subcategories: z.lazy(() => z.array(CategorySchema)),\n});\n\nconst UserSchema = z.object({\n  username: z.string().describe('User\\'s unique identifier'),\n  age: z.number().int().positive(),\n  roles: z.array(z.literal('admin').or(z.literal('editor')).or(z.literal('viewer'))),\n  inventory: z.object({\n    name: z.string().min(1),\n    itemId: z.number().int().positive(),\n    quantity: z.number().int().min(0).optional(),\n  }).array().describe('List of user\\'s owned items'),\n  favoriteCategory: CategorySchema,\n});\n\nconst auxiliaryTypeStore = createAuxiliaryTypeStore();\nconst { node: userNode } = zodToTs(UserSchema, { auxiliaryTypeStore });\n\nconst userTypeAlias = createTypeAlias(userNode, 'User');\nconst userTypeString = printNode(userTypeAlias);\nconsole.log('--- User Type ---');\nconsole.log(userTypeString);\n\nconsole.log('\\n--- Auxiliary Types (for recursion) ---');\n// Extract and print auxiliary types if any (e.g., for CategorySchema recursion)\nconst auxiliaryTypePreamble = Array.from(auxiliaryTypeStore.definitions.values())\n  .map((definition) => printNode(definition.node))\n  .join('\\n');\nconsole.log(auxiliaryTypePreamble);\n","lang":"typescript","description":"Demonstrates converting complex Zod object schemas, including nested objects, arrays, and recursive structures, into TypeScript type aliases and printing them, showing how auxiliary types are generated for recursion."},"warnings":[{"fix":"Ensure your project uses `zod@^4.0.0` or higher. Upgrade Zod if necessary using `npm install zod@^4`.","message":"Version 2.0.0 of `zod-to-ts` dropped support for Zod v3. Only Zod v4 and newer versions are supported for runtime schema processing.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Update your type override configuration to use the new `Map`-based API as described in the documentation.","message":"The API for overriding types changed in v2.0.0. The `overrides` option is now expected to be a `Map` of Zod types to custom TypeScript nodes, replacing previous object-based configurations.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"To bypass the error and generate `any` for unrepresentable types, pass `{ unrepresentable: 'any' }` in the options object to `zodToTs`. Alternatively, refactor your schema to avoid these constructs if strict type generation is required.","message":"Zod APIs like `z.transform()` and `z.custom()` cannot be accurately represented as static TypeScript types. By default, `zod-to-ts` will throw an error if these are encountered.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Before calling `zodToTs` with a recursive schema, initialize `const auxiliaryTypeStore = createAuxiliaryTypeStore()` and pass it in the options: `{ auxiliaryTypeStore }`. Remember to process the `auxiliaryTypeStore.definitions` for all generated helper types.","message":"Recursive Zod schemas (e.g., an object referencing itself) require the `createAuxiliaryTypeStore` and passing an `auxiliaryTypeStore` instance to `zodToTs` to generate correct helper types. Without it, the generated type node might be incomplete or incorrect.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Upgrade your `zod` package to version 4 or higher: `npm install zod@^4`.","cause":"Attempting to use `zod-to-ts` v2 with an incompatible Zod v3.x installation.","error":"Error: Zod schema version mismatch. `zod-to-ts` v2.x requires Zod v4.x."},{"fix":"Pass `{ unrepresentable: 'any' }` in the options object to `zodToTs` to allow `any` to be generated for unrepresentable types, or modify your Zod schema to avoid these constructs.","cause":"A `z.transform()` or `z.custom()` Zod schema was encountered without configuring the `unrepresentable` option.","error":"Error: Cannot represent a Zod schema of type 'ZodTransformer' as a TypeScript type."},{"fix":"Use `Array.from(auxiliaryTypeStore.definitions.values())` to correctly convert the iterator into an array before further processing like `map()`.","cause":"Trying to iterate over the `Map.prototype.values()` iterator returned by `auxiliaryTypeStore.definitions.values()` by calling a non-existent `toArray()` method directly.","error":"TypeError: (intermediate value).toArray is not a function"}],"ecosystem":"npm"}