Quiero tener un componente de entrada no controlado reutilizable usando react-hook-form , pero parece que no puedo obtener los tipos correctos.
Algo como esto:
Enlace de CodeSandbox con el ejemplo.
Obs.: El código parece funcionar bien. Creo que solo es cuestión de ajustar los tipos.
// REUSABLE UNCONTROLLED INPUT interface NoteInputValue extends FieldValues { note: string; } type NoteInputProps = { register: UseFormRegister<NoteInputValue>; }; const NoteInput: React.FC<NoteInputProps> = (props) => { const { register } = props; return <input {...register("note")} />; };Este es el componente del formulario:
// SOME FORM COMPONENT THAT NEEDS // TO USE THE INPUT interface FormValues extends FieldValues { note: string; someOtherField: boolean; } type MyFormProps = {}; const MyForm: React.FC<MyFormProps> = (props) => { const { register } = useForm<FormValues>({ defaultValues: { note: "", someOtherField: true } }); return ( <> <NoteInput register={register} /> </> ); };Este es el error de TypeScript que recibo:
Solo para documentarlo aquí, encontré dos enfoques que podrían funcionar, pero no son ideales, en mi opinión. Mi objetivo final es simplemente pasar la función de register y debería poder registrar el name de la entrada de la que ya tiene conocimiento, sin recibir el name como accesorios.
https://codesandbox.io/s/modest-brook-2yknnc
// REUSABLE UNCONTROLLED INPUT interface InputValue { note: string; } interface NoteInputProps<FormValues> { register: UseFormRegister<FormValues>; } const NoteInput = <FormValues extends InputValue>( props: NoteInputProps<FormValues> ) => { const { register } = props; // Note: // Couldn't get rid of the `name` type assertion as Path<FormValues>. // Even though `FormValues extends InputValue` (so it must // have the `note` field). We get an error if we try to call // register('note') without the type assertion const name = "note" as Path<FormValues>; return <input {...register(name)} />; }; O, pasando el name explícitamente (que era lo que estaba tratando de evitar):
https://codesandbox.io/s/objective-northcutt-9hb5t2?file=/src/App.tsx
// REUSABLE UNCONTROLLED INPUT interface InputValue { note: string; } interface NoteInputProps<FormValues> { name: FieldPath<FormValues>; register: UseFormRegister<FormValues>; } const NoteInput = <FormValues extends InputValue>( props: NoteInputProps<FormValues> ) => { const { name, register } = props; return <input {...register(name)} />; };