使用Zod+Modular Forms+TypeScript时遇类型实例化过深问题
使用Zod、@modular-forms/solid与TypeScript开发表单时的类型问题
表单校验代码
import { z } from 'zod'; import type { infer as zodInfer } from 'zod'; export const registrationFormSchema = z.object({ nom: z.string().min(1, 'El nom és obligatori'), dataNaixement: z.string().min(1, 'La data de naixement és obligatòria'), telefonContacte: z.string().min(9, 'El telèfon de contacte ha de tenir almenys 9 dígits'), telefonEmergencia: z.string().min(9, 'El telèfon d\'emergència ha de tenir almenys 9 dígits'), }).refine( (data) => data.telefonContacte !== data.telefonEmergencia, { message: 'El telèfon de contacte i el telèfon d\'emergència no poden ser els mateixos', path: ['telefonEmergencia'], } ); export type TRegistrationForm = zodInfer<typeof registrationFormSchema>; export const registrationFormInitialValues: TRegistrationForm = { nom: '', dataNaixement: '', telefonContacte: '', telefonEmergencia: '', };
组件使用与报错情况
初始写法及报错
import { createForm, zodForm } from '@modular-forms/solid' import { registrationFormSchema, type TRegistrationForm, registrationFormInitialValues } from '../schema'; const [form, { Field }] = createForm<TRegistrationForm>({ initialValues: registrationFormInitialValues, validate: zodForm<TRegistrationForm>(registrationFormSchema) });
收到错误提示:
Argument of type 'ZodEffects<ZodObject<{ nom: ZodString; dataNaixement: ZodString; telefonContacte: ZodString; telefonEmergencia: ZodString; }, "strip", ZodTypeAny, { ...; }, { ...; }>, { ...; }, { ...; }>' is not assignable to parameter of type 'ZodType<any, any, { nom: string; dataNaixement: string; telefonContacte: string; telefonEmergencia: string; }>'.
修改后写法及报错
去掉zodForm的泛型参数后:
const [form, { Form, Field }] = createForm<TRegistrationForm>({ initialValues: registrationFormInitialValues, validate: zodForm(registrationFormSchema) });
收到错误提示:
Type instantiation is excessively deep and possibly infinite
问题根源与解决思路
第一个错误原因:
经过refine处理后的registrationFormSchema是ZodEffects类型,而手动给zodForm<TRegistrationForm>指定的泛型期望接收原始ZodType,两者类型不匹配导致报错。第二个错误原因:
ZodEffects的嵌套类型结构触发了TypeScript的类型递归深度限制,导致类型实例化过深。可行解决方法:
- 优先推荐:自动类型推断
去掉所有手动指定的泛型参数,让TypeScript从schema和初始值自动推断类型:const [form, { Field }] = createForm({ initialValues: registrationFormInitialValues, validate: zodForm(registrationFormSchema) }); - 类型断言绕过检查(临时方案)
如果必须手动指定类型,可通过类型断言将ZodEffects转为目标类型:const [form, { Field }] = createForm<TRegistrationForm>({ initialValues: registrationFormInitialValues, validate: zodForm(registrationFormSchema) as z.ZodType<TRegistrationForm> }); - 依赖版本升级
检查@modular-forms/solid版本,旧版本对Zod的refine支持可能存在缺陷,升级到最新版本可解决部分类型递归问题。
- 优先推荐:自动类型推断
内容的提问来源于stack exchange,提问作者Jordi Cabré
相关产品推荐
相关产品推荐

