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.
In v2, a component may need to accept a form created from one of several sets of form options:
TypeScript cannot resolve the resulting union of form types correctly. Once
formis typed asForm1 | Form2, members such asform.Fieldare 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 typeAtherefore 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:
formOptionswhose data type is a union;TDatato one of its members (TGuard);TGuard; andTDataform and narrow it to the correspondingTGuardform.