-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
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:
- Uses
provide/injectinternally, losing the direct connection to the typed form - Accepts any
stringpath, not just paths that resolve to arrays - The array item type must be manually specified:
useFieldArray<MyItemType>('items')
This creates an inconsistency:
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 pathDescribe the solution you'd like
Add a defineArrayField function to the useForm return object that mirrors defineField:
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) => voidAPI:
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
defineFieldpattern - No need for
provide/injectwhen used withuseForm
Describe alternatives you've considered
-
Use
useFieldArrayin the same component asuseForm- Works, but loses type safety. The inject still finds the form, but the path is untyped. -
Manually type
useFieldArray<ItemType>('path')- Works, but requires manual type annotation and doesn't validate the path. -
Create a wrapper function - Users could wrap
useFieldArraythemselves, but this should be a first-class API sincedefineFieldalready 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:
- Form passed directly (no inject)
- Path constrained to
ArrayPath<TValues> - Item type inferred from
PathValue
I have an implementation ready and would be happy to submit a PR if there's interest.