📝

React Hook Form と Zod を利用して Submit 時の型が合うようになっていた

2024/10/14に公開

今までめっちゃ zod で transform とかしたらアウトプットの型が違うので困ってた

const schema = z
  .object({
    firstName: z.string().min(1),
    lastName: z.string().min(1),
  })
  .transform(({ firstName, lastName }) => ({
    fullName: `${firstName} ${lastName}`,
  }));

// { firstName: string; lastName: string; }
type InputSchema = z.input<typeof schema>;

const { handleSubmit } = useForm<DeepPartial<InputSchema>>({
    resolver: zodResolver(schema),
});

const onSubmit = handleSubmit((data) => {
  // 🙅 data の型が値一致しない
  // data の型 { firstName: string; lastName: string; }
  // data の値 { fullName: "..." }
  alert(data.fullName);
});

7.44.0 から TTransformedValues がサポートされてた

useForm support TTransformedValues

https://github.com/react-hook-form/react-hook-form/releases/tag/v7.44.0-rc.0

const schema = z
  .object({
    firstName: z.string().min(1),
    lastName: z.string().min(1),
  })
  .transform(({ firstName, lastName }) => ({
    fullName: `${firstName} ${lastName}`,
  }));

// { firstName: string; lastName: string; }
type InputSchema = z.input<typeof schema>;
// { fullName: string; }
type OutputSchema = z.output<typeof schema>;

const { handleSubmit } = useForm<DeepPartial<InputSchema>, any, OutputSchema>({
    resolver: zodResolver(schema),
});

const onSubmit = handleSubmit((data) => {
  // 🙆 data の型が値一致する
  // data の型 { fullName: string }
  // data の値 { fullName: "..." }
  alert(data.fullName);
});

動作確認
https://codesandbox.io/p/sandbox/react-hook-form-support-ttransformedvalues-x93wzw

ただドキュメントを見る限りではまだ含まれていないみたいなのが気になる
https://react-hook-form.com/ts#UseFormReturn

Discussion