Millenial2020
Millenial2020

Reputation: 2941

Typescript React How to add an a second interface to Prop

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.

Upvotes: 1

Views: 430

Answers (1)

ghybs
ghybs

Reputation: 53370

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>
    );
};

Playground Link

Upvotes: 1

Related Questions