简体   繁体   中英

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM