Svelte+TypeScript中数字输入绑定与Zod校验问题
解决Svelte + shadcn-svelte + Zod表单数字输入类型不匹配问题
方案1:用Zod的强制转换(最推荐)
直接修改Zod schema,把z.number()换成z.coerce.number()——它会自动将输入的字符串转为数字,同时保留数字校验逻辑:如果输入无法转成有效数字(比如字母),依然会抛出错误。
修改后的schema代码:
// schema.ts const formSchema = z.object({ /* ... */ maxParticipants: z.coerce.number() });
输入框保持type="number"不变,提交时Zod会自动完成类型转换和校验。
方案2:在Svelte中实时转换输入值
如果不想改动Zod schema,可以在组件里通过响应式语句,把输入的字符串实时转为数字:
<!-- form.svelte --> <Form.Field {form} name="maxParticipants"> <Form.Control let:attrs> <Form.Label>Max participants</Form.Label> <Input {...attrs} type="number" bind:value={$formData.maxParticipants} /> </Form.Control> <Form.FieldErrors /> </Form.Field> <script> // 实时转换,空值按需设为undefined或0 $: if ($formData.maxParticipants !== '') { $formData.maxParticipants = Number($formData.maxParticipants); } else { $formData.maxParticipants = undefined; } </script>
这种方法能确保$formData里的maxParticipants始终是数字类型,适配原有的Zod z.number()校验规则。
方案3:通过表单配置统一转换字段类型
如果使用@hookform/resolvers结合Zod创建表单,可以在初始化时添加转换逻辑,提交前统一处理字段类型:
// 创建form的代码 const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { /* ... */ maxParticipants: 0 }, // 提交前转换字段类型 transformValues: (values) => ({ ...values, maxParticipants: Number(values.maxParticipants) }) });
这个方法适合需要批量处理多个数字输入字段的场景。
内容的提问来源于stack exchange,提问作者imstuck
相关产品推荐
相关产品推荐

