Capítulo 28 de 29

Chapter 28: Utility & State Types

Core Idea

A handful of type aliases underpin the whole type-inference story: DeepKeys/DeepValue compute dot-path field names and their value types from defaultValues, BaseFormState/DerivedFormState describe what's actually in form.state, and Updater/ValidationError/ValidationMeta are small supporting shapes used throughout the API.

Reference Tables

Inference primitives

TypePurpose
DeepKeys<T>Computes every valid dot-path field name for a (possibly deeply nested) object type T — this is what makes a typo in form.Field's name prop a compile error
DeepValue<T, Path>Given a T and a DeepKeys<T> path, resolves the value type at that path — what makes field.state.value correctly typed per-field

Form state

Field (on BaseFormState, extended by DerivedFormState)Purpose
valuesCurrent values of every field
errorMapErrors keyed by validation trigger (onChange/onBlur/onSubmit/onDynamic, ch027)
fieldMetaBasePer-field metadata, excluding derived/computed properties
formGroupStateBaseSubmission lifecycle state for any mounted FormGroup (ch012)
isSubmittingTrue while a submission is in flight
isSubmittedResets to false at the start of each new submission attempt
isSubmitSuccessfulWhether the most recent submission completed without error
isValidatingTrue while the form or any field is mid-validation
submissionAttemptsRunning count of submit attempts (useful input to revalidateLogic's "after first submit" logic, ch009)
validationMetaMapInternal validation-tracking metadata
(DerivedFormState adds) isValid / canSubmitComputed convenience booleans layered on top of the base state fields above

Small supporting types

TypePurpose
Updater<T>The general "either a new T, or a function from old T to new T" shape accepted by every set* method (setFieldValue, setValue, etc.)
UpdaterFn<T>The function-form half of Updater<T> specifically
ValidationErrorTyped as unknown on purpose — any truthy value is a valid error (ch016 Custom Errors)
ValidationMetaMetadata carried alongside a validation run (e.g. for cancellation of superseded async validations)
AnyFieldMetaThe type-erased field-metadata shape (isTouched/isDirty/errors/etc.) used where a field's exact generic parameters aren't known

Key Takeaways

  1. DeepKeys/DeepValue are why form.Field name="typo" is a compile-time error instead of a silent runtime no-op — understanding these two types explains most of the library's "magical" type safety.
  2. isValid/canSubmit are derived (DerivedFormState), not stored directly — they're computed from the base error/validation state on every read, not fields you'd manually set.
  3. Every set* method across FormApi/FieldApi (ch026) accepts an Updater<T> — you can always pass either a plain new value or an updater function, exactly like useState's setter overload.

Connects To

  • Ch005 TypeScript: the strict/version requirements these inference types depend on.
  • Ch026 Field & Form API Classes: the classes whose state this chapter's types describe.
  • Ch016 Custom Errors: why ValidationError is deliberately typed as unknown.