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>
);
};
I'm trying to add the DetailedHTMLProps<FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>
data type for the form not sure what's the right way of doing that.
Use extends
to say that the FormProps
interface is made of the same content as your desired type, as well as extra properties that you specify.
Make sure not to collide the property names, or if you do so intentionally, the collided properties must have compatible types. In your case, onSubmit
and children
collide with properties in DetailedHTMLProps<FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>
and have incompatible types; you could just use different names instead.
interface FormProps<TFormValues extends FieldValues> extends
DetailedHTMLProps<FormHTMLAttributes<HTMLFormElement>, HTMLFormElement> {
// Make sure not to collide properties with incompatible types
submitHandler: SubmitHandler<TFormValues>;
methodsHandler: (methods: UseFormReturn<TFormValues>) => ReactNode;
}
export const Form = <TFormValues extends Record<string, any>>({
submitHandler,
methodsHandler,
...formAttrs
}: FormProps<TFormValues>) => {
const methods = useForm<TFormValues>();
return (
<form onSubmit={methods.handleSubmit(submitHandler)} {...formAttrs}>{methodsHandler(methods)}</form>
);
};