zod icon indicating copy to clipboard operation
zod copied to clipboard

Zod v4: Transform function loses type inference with generic functions and causes issues with implementAsync

Open luis-barroso opened this issue 2 months ago • 3 comments

I have created a minimal reproduction repository here: https://github.com/luis-barroso/zod-v4-test This repository uses zod v4. With zod v3, none of these errors occur. If you use this repository and run npm run compile, you can see the 2 errors described below.

It appears that generic functions that take zod schemas as input and that return a new zod schema do not work well with the transform function. The transform function loses all type inference and returns a very complex and unreadable type that does not work as expected (check the index.ts file in the reproduction repository).

Image

A second issue that I found is when I use a type guard function to narrow the possible values in the transform function and although it shows the correct values if I hover over the property, it seems to cause issues with the implementAsync function (check the error.ts file in the reproduction repository). If I do not use the type guard function then I get no errors (check the no-errors.ts file in the reproduction repository).

Image

luis-barroso avatar Nov 18 '25 15:11 luis-barroso

Hi @luis-barroso! I'm Dosu and I’m helping the zod team.

I'm a bot trained on Zod's codebase and issues. These behaviors in Zod v4 are a result of TypeScript's inference limits and recent architectural changes in Zod, not runtime bugs.

For the transform/generics issue: when you use a generic function to build a schema and then call .transform, TypeScript often loses track of the object's property types, so you get errors like "Property 'code' does not exist on type..." and unreadable types. This is due to how TypeScript handles mapped types and optional properties in generics, especially with Zod's internal utilities like addQuestionMarks and the new ZodTransform/ZodPipe architecture in v4. This is discussed in detail in issue #3309, issue #5198, and issue #1977.

Workarounds:

  • Use a type assertion inside your transform callback, e.g. (data) => (data as { code: string }).code.
  • Or, add an explicit type annotation to the transform parameter, but be aware this can sometimes cause TypeScript errors about missing properties due to how Zod v4 handles optionals. In that case, relax the type or use a type assertion.
  • See #5198 and #3537 for more examples.

For the type guard + implementAsync issue: Zod v4 no longer narrows types with type predicates in refinements or transforms as v3 did (changelog). This can cause type conflicts or errors when you use type guards in a transform and then try to use implementAsync, because the narrowed type isn't propagated as you might expect.

Workarounds:

  • Avoid using type guards in transforms if you need to use implementAsync, or ensure your function signatures and schema outputs are explicitly typed to match what Zod expects.
  • If you need async transforms, always use .parseAsync or .safeParseAsync (docs).

These are TypeScript inference edge cases and tradeoffs from Zod v4's new type system. If you want to dig deeper, see the linked issues for detailed explanations and more workarounds.

If this answers your question, please close the issue! If you need more help, let me know.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

dosubot[bot] avatar Nov 18 '25 16:11 dosubot[bot]

@dosu I would rather have a member of the zod team check out the repository and see the errors for themselves. These do not seem errors that are intended to happen with the new version.

luis-barroso avatar Nov 18 '25 16:11 luis-barroso

I'm a bot trained on Zod's codebase and issues, so I can't personally review code or run tests. I've flagged your request for a maintainer review.

@colinhacks, the user has provided a minimal reproduction repo (https://github.com/luis-barroso/zod-v4-test) that demonstrates two TypeScript errors in Zod v4 related to transform and generics, and to type guards with implementAsync, which did not occur in Zod v3. The user believes these are not intended behaviors in Zod v4 and would like a human maintainer to review the repo and errors directly.

If you need more technical context or links to related issues and workarounds, let me know!

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

dosubot[bot] avatar Nov 18 '25 16:11 dosubot[bot]

I have not been able to fix this issue without also breaking Zod's recursive type inference. I'm quite confident there is a fundamental TypeScript limitation here.

colinhacks avatar Dec 16 '25 04:12 colinhacks