You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-hook-form与Zod类型推断错误问题排查与解决

Type 'string' is not assignable to type 'Date' 错误分析与修复

问题代码

const scheme = z.object({
  date: z
    .string()
    .transform((value) => value)
    .pipe(z.coerce.date()),
})

const useForm = <TFieldValues extends FieldValues>(options: {
    scheme: z.Schema<TFieldValues>
}) => {
    const { scheme } = options
    
    return useRHForm<TFieldValues>({
        resolver: zodResolver(scheme),
    })
}

useForm({
    scheme, // Type 'string' is not assignable to type 'Date'.
})

调用useForm时出现类型错误:Type 'string' is not assignable to type 'Date'


错误原因

  • 你的Zod schema里,date字段通过.pipe(z.coerce.date())实现了输入是string、输出是Date的类型转换,但Zod的z.Schema<T>默认描述的是schema的输出类型(也就是转换后的Date类型)。
  • 封装的useRHForm(react-hook-form实例)中,TFieldValues对应的是表单的输入值类型(用户实际输入的string类型),两者类型不匹配,触发TypeScript报错。
  • 当前useForm的泛型参数直接把TFieldValues绑定到了schema的输出类型,没有区分输入和输出的类型差异,这是问题核心。

修复方案

修改useForm的泛型定义,利用Zod内置的类型提取工具,区分schema的输入和输出类型,让表单输入类型和schema的输入类型对齐:

import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { FieldValues, useForm as useRHForm } from "react-hook-form";

const scheme = z.object({
  date: z
    .string()
    .transform((value) => value)
    .pipe(z.coerce.date()),
});

// 提取Zod schema的输入类型
type SchemaInput<T extends z.Schema> = z.inferInput<T>;

const useForm = <TSchema extends z.Schema>(options: {
    scheme: TSchema
}) => {
    const { scheme } = options;
    // 让useRHForm的泛型使用schema的输入类型
    return useRHForm<SchemaInput<TSchema>>({
        resolver: zodResolver(scheme),
    });
};

// 调用不再报错
useForm({
    scheme,
});

如果业务场景需要表单字段值直接使用转换后的Date类型,可以在useRHForm中配置defaultValues并设置合适的校验模式确保类型完全对齐,但更推荐上面的方案——因为表单初始输入通常为string类型。


内容的提问来源于stack exchange,提问作者Pavel Perevezencev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 11:23:16