TanStack / TanStack/form

[v2] Support type narrowing for union form types

Open
#2,297 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area: types scope: core type: enhancement
Dominant language
TypeScript
Stars
6.7k
Forks
682
Avg merge
5d 18h
Merged PRs (30d)
7

Description

In v2, a component may need to accept a form created from one of several sets of form options:

const formVariant1 = formOptions(/* ... */)
const formVariant2 = formOptions(/* ... */)

type Form1 = ReactFormType<typeof formVariant1>
type Form2 = ReactFormType<typeof formVariant2>


interface MyComponentProps {
  form: Form1 | Form2
}

TypeScript cannot resolve the resulting union of form types correctly. Once form is typed as Form1 | Form2, members such as form.Field are no longer available.

A related problem occurs when a form's values are represented by a union. Even after checking a discriminant, such as form.state.values.type === 'A', TypeScript does not narrow the type of the form itself. APIs that are only valid for type A therefore remain unavailable even though the value has already been narrowed.

It would be useful to have an API that narrows the form alongside its values. A user could provide a type predicate for one member of the union and, when that predicate succeeds, work with a form typed specifically for that member.

Some thoughts

The exact API is open for discussion, but a possible design would:

  • accept formOptions whose data type is a union;
  • accept a callback that acts as a type predicate, narrowing TData to one of its members (TGuard);
  • expose a form type narrowed to TGuard; and
  • provide a function, essentially a wrapper around the original predicate, that can accept the TData form and narrow it to the corresponding TGuard form.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the TypeScript definitions for formOptions and ReactFormType, focusing on how union form types and union values are represented. Compare the desired type-predicate behavior with the existing form API. Done means a predicate can narrow the form to the corresponding union member and members such as form.Field remain available after narrowing.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.