如何为React TypeScript表单组件的Props添加第二个接口
如何将HTML表单原生属性类型集成到自定义React Hook Form组件的Props中
原始代码
import { ReactNode, DetailedHTMLProps, FormHTMLAttributes } from "react"; import { FieldValues, SubmitHandler, useForm, UseFormReturn, } from "react-hook-form"; // I want to add this type to the FormProps interface // DetailedHTMLProps<FormHTMLAttributes<HTMLFormElement>, HTMLFormElement> interface FormProps<TFormValues extends FieldValues> { onSubmit: SubmitHandler<TFormValues>; children: (methods: UseFormReturn<TFormValues>) => ReactNode; } export const Form = <TFormValues extends Record<string, any>>({ onSubmit, children, }: FormProps<TFormValues>) => { const methods = useForm<TFormValues>(); return ( <form onSubmit={methods.handleSubmit(onSubmit)}>{children(methods)}</form> ); };
问题需求
希望让自定义Form组件支持所有原生HTML表单的属性,需要将DetailedHTMLProps<FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>类型集成到FormProps接口中。
解决方案
通过接口扩展+类型排除实现,既保留原生表单属性的类型支持,又避免与组件自定义的onSubmit属性冲突:
- 让
FormProps扩展原生表单属性类型,但用Omit排除原生的onSubmit(因为组件需要的是react-hook-form的SubmitHandler类型,而非原生表单的提交事件类型) - 将剩余的原生属性解构后传递给底层的
<form>元素
修改后的完整代码:
import { ReactNode, DetailedHTMLProps, FormHTMLAttributes } from "react"; import { FieldValues, SubmitHandler, useForm, UseFormReturn, } from "react-hook-form"; interface FormProps<TFormValues extends FieldValues> extends Omit<DetailedHTMLProps<FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, 'onSubmit'> { onSubmit: SubmitHandler<TFormValues>; children: (methods: UseFormReturn<TFormValues>) => ReactNode; } export const Form = <TFormValues extends FieldValues>({ onSubmit, children, ...rest // 解构所有原生表单属性 }: FormProps<TFormValues>) => { const methods = useForm<TFormValues>(); return ( // 将原生属性传递给底层form标签 <form {...rest} onSubmit={methods.handleSubmit(onSubmit)}> {children(methods)} </form> ); };
说明
- 使用
Omit排除原生onSubmit:原生表单的onSubmit类型是(e: FormEvent<HTMLFormElement>) => void,与组件需要的SubmitHandler<TFormValues>类型不兼容,因此必须排除后重新定义 - 通过
...rest接收并传递原生属性:这样你的自定义Form组件就可以像原生<form>标签一样使用所有属性,比如className、style、id、enctype、autocomplete等 - 统一泛型约束:将组件的泛型约束从
Record<string, any>改为FieldValues,与接口的约束保持一致,更符合react-hook-form的类型规范
内容的提问来源于stack exchange,提问作者Millenial2020
相关产品推荐
相关产品推荐

