Add defineArrayField for type-safe array field management (mirrors defineField pattern)

Author: zalmentCreated Jan 19, 2026Updated Jan 19, 2026

Is your feature request related to a problem? Please describe.

When using useForm with TypeScript, defineField provides excellent type safety - it constrains paths to valid form paths and infers the correct value type.

However, for array fields, we must use useFieldArray which:

  1. Uses provide/inject internally, losing the direct connection to the typed form
  2. Accepts any string path, not just paths that resolve to arrays
  3. The array item type must be manually specified: useFieldArray<MyItemType>('items')

This creates an inconsistency:

typescript
const { defineField } = useForm<MyForm>();

// ✅ Type-safe: path is constrained, value type is inferred
const [name] = defineField('user.name'); // Ref<string>

// ❌ Not type-safe: any string accepted, item type not inferred
const { fields } = useFieldArray<Item>('items'); // Manual type required
const { fields } = useFieldArray('typo'); // No error for invalid path

Describe the solution you'd like

Add a defineArrayField function to the useForm return object that mirrors defineField:

typescript
const { defineField, defineArrayField } = useForm<MyForm>();

// Type-safe array field management:
// - Only accepts paths that resolve to array types (ArrayPath<TValues>)
// - Infers the array item type automatically
const { fields, push, remove } = defineArrayField('items');
//      ^-- FieldEntry<Item>[]     ^-- (item: Item) => void

API:

typescript
defineArrayField<TPath extends ArrayPath<TValues>>(
  path: MaybeRefOrGetter<TPath>
): FieldArrayContext<InferredItemType>

Benefits:

  • Path autocomplete only shows array paths
  • TypeScript error if path doesn't resolve to an array
  • Array item type is automatically inferred
  • Consistent with defineField pattern
  • No need for provide/inject when used with useForm

Describe alternatives you've considered

  1. Use useFieldArray in the same component as useForm - Works, but loses type safety. The inject still finds the form, but the path is untyped.

  2. Manually type useFieldArray<ItemType>('path') - Works, but requires manual type annotation and doesn't validate the path.

  3. Create a wrapper function - Users could wrap useFieldArray themselves, but this should be a first-class API since defineField already exists for single fields.


Additional context

This mirrors the existing relationship in the codebase:

Single Field Array Field
inject-based useField useFieldArray
form-direct (typed) defineField defineArrayField ❌ (missing)

The implementation would reuse the existing useFieldArray logic internally, just with:

  1. Form passed directly (no inject)
  2. Path constrained to ArrayPath<TValues>
  3. Item type inferred from PathValue

I have an implementation ready and would be happy to submit a PR if there's interest.