resolvers icon indicating copy to clipboard operation
resolvers copied to clipboard

issue: zodResolver types `z.union` incorrectly in Zod v4

Open Garrett-R opened this issue 4 months ago • 0 comments

Version Numbers

zodResolver: 5.2.1 react-hook-form: 7.62.0 zod: 4.0.17

Codesandbox/Expo snack

StackBlitz (Codesandbox had bug)

Steps to reproduce

Observe this code snippet (or see link above):

import { zodResolver } from '@hookform/resolvers/zod';
import { ReactElement } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';

const SubSchemaA = z.strictObject({
  isA: z.literal(true),
});
const SubSchemaB = z.strictObject({
  isA: z.literal(false),
});

const MySchema = z.union([SubSchemaA, SubSchemaB]);
export type MySchemaInput = z.input<typeof MySchema>;

interface FooProps {
  defaultVals: MySchemaInput;
}

export function Foo({ defaultVals }: FooProps): ReactElement {
  const { register } = useForm({
    resolver: zodResolver(MySchema),
    defaultValues: defaultVals,
  });

  return <h1>Zod Form</h1>;
}

Expected behaviour

This should have no type errors, but you get a type error on defaultValues saying:

Type '{ isA: true; } | { isA: false; }' is not assignable to type 'AsyncDefaultValues<{ isA: true; }> | { isA?: true | undefined; } | undefined'.

It seems zodResolver doesn't understand that isA can be false.

Code of Conduct

  • [x] I agree to follow this project's Code of Conduct

keywords: discriminating union

Garrett-R avatar Aug 20 '25 22:08 Garrett-R