Capítulo 3 de 39

Chapter 3: TypeScript Support

Core Idea

React Hook Form exports a large set of named TypeScript types so every return value, prop, and callback of every hook/component can be typed explicitly (useful for custom wrapper components); TypeScript 4.1+ is required because several types rely on recursive generics for field-path inference.

Key Concepts

  • TFieldValues / TContext / TTransformedValues: the three generics most RHF types share — form values shape, an arbitrary context object forwarded to resolver, and the shape a resolver's .transform() produces (defaults to TFieldValues).
  • Resolver: (values) => { values, errors } — the type for plugging in Zod/Yup/Joi/etc. instead of built-in rules.
  • SubmitHandler / SubmitErrorHandler: types for handleSubmit's valid/invalid callbacks; FormSubmitHandler is the <Form> component's variant whose payload also carries raw FormData/formDataJson.
  • UseFormReturn: the full shape returned by useForm() — every method (register, control, handleSubmit, watch, subscribe, setValue, setValues, getValues, getErrors, getFieldState, setError, clearErrors, trigger, reset, resetField, resetDefaultValues, unregister, setFocus, formState) has its own named type (UseFormRegister, UseFormWatch, UseFormSetValue, etc.) for typing custom components that receive just one of them as a prop.
  • ValidateForm: the type of useForm's validate option — form-level validation that runs alongside or instead of a resolver, returning true, a string (sets errors.form), or a field-keyed object (sets errors.form.<field>).
  • Field-path types: FieldPath<T>, FieldPathByValue<T, V>, FieldValues, FieldArrayWithId — the generic machinery that makes register("firstName") type-check against your form's actual shape.
  • RegisterOptions / FormState / Mode / KeepStateOptions: the option/state shapes for register's validation rules, formState's flags, useForm's mode/reValidateMode, and the keepX flags accepted by reset/unregister.
  • Controller-specific types: ControllerProps, ControllerRenderProps, ControllerFieldState, UseControllerProps, UseControllerReturn — typing for the Controller component and useController hook.
  • NestedValue: deprecated since 7.33.0 — no longer needed for typing nested object/array field values.

Code Examples

import { useForm, Resolver } from "react-hook-form"

type FormValues = { firstName: string; lastName: string }

const resolver: Resolver<FormValues> = async (values) => ({
  values: values.firstName ? values : {},
  errors: !values.firstName
    ? { firstName: { type: "required", message: "This is required." } }
    : {},
})

const { register, handleSubmit, formState: { errors } } = useForm<FormValues>({ resolver })
  • What it demonstrates: a hand-written Resolver — the same shape schema-library adapters (@hookform/resolvers/zod, /yup, …) implement.

Reference Tables

TypeWhat it types
Resolverexternal validation function passed to useForm({ resolver })
SubmitHandler / SubmitErrorHandlerhandleSubmit's valid/invalid callbacks
UseFormReturneverything useForm() returns
UseFormPropseverything useForm(options) accepts
Controlthe control object passed to Controller/useController/useWatch/useFieldArray
FieldPath<T>a valid dot-path field name for form values type T
RegisterOptionsthe second argument to register(name, options)
FormState<T>shape of formState (errors, isDirty, dirtyFields, touchedFields, isSubmitting, isValid, …)
UseFieldArrayProps / UseFieldArrayReturnuseFieldArray's options and return (fields, append, remove, replace, …)
ControllerProps / UseControllerPropsController component props / useController hook props

Key Takeaways

  1. Every method on useForm()'s return value has its own exported type (UseFormRegister, UseFormSetValue, …) — use these to type a component that only receives one method as a prop, instead of the whole UseFormReturn.
  2. Resolver<TFieldValues, TContext, TTransformedValues> is the type to implement (or match) when building a custom schema adapter.
  3. FieldPath<TFieldValues> is what makes register("someField") reject typos against your form's declared shape.
  4. NestedValue is deprecated — don't reach for it in new code.

Connects To

  • useform: the hook whose full return type is UseFormReturn.
  • usecontroller / usecontroller-controller: the types listed under "Controller-specific types" apply here.
  • usefieldarray: UseFieldArrayProps/UseFieldArrayReturn/FieldArrayWithId.
  • useform-register: RegisterOptions is the validation-rules object type accepted here.