如何基于Zod Schema定义BaseFormProps的onSubmit参数类型?
用泛型实现onSubmit参数类型与Schema关联
当然可以实现,但没法直接在普通类型定义里引用自身的schema属性来推导类型,得用泛型处理这种类型依赖关系,具体实现如下:
修改后的BaseFormProps类型定义
import { z } from "zod"; import type { ReactNode } from "react"; // 定义泛型类型,接收Zod schema作为参数 type BaseFormProps<SchemaType extends z.ZodTypeAny> = { className?: string; labelClassName?: string; inputClassName?: string; schema: SchemaType; children?: ReactNode; onChange?: (errors: z.ZodIssue[]) => void; // 顺便把errors替换为Zod原生错误类型,比any更严谨 onSubmit: (data: z.infer<SchemaType>) => void; };
使用示例
当你传入具体的Zod Schema时,TypeScript会自动推导onSubmit的data参数类型:
// 示例:创建一个用户表单的Zod Schema const UserSchema = z.object({ name: z.string(), age: z.number().min(18), email: z.string().email() }); // 定义表单组件时,TS会自动根据UserSchema推导data类型 const UserForm: React.FC<BaseFormProps<typeof UserSchema>> = ({ schema, onSubmit }) => { return ( <form onSubmit={(e) => { e.preventDefault(); // 模拟获取表单数据 const formData = { name: "张三", age: 25, email: "zhangsan@example.com" }; const validateResult = schema.safeParse(formData); if (validateResult.success) { // 这里data的类型会被自动推断为{ name: string; age: number; email: string } onSubmit(validateResult.data); } }} > {/* 表单元素 */} </form> ); };
原理说明
泛型是TypeScript处理这种“属性类型互相依赖”场景的标准方案:通过把Schema的类型抽成泛型参数,让onSubmit的data类型直接基于这个参数推导,这样就能保证data的类型始终和传入的schema完全匹配。
内容的提问来源于stack exchange,提问作者T00rk
相关产品推荐
相关产品推荐

