Lack of Type Safety with Pre-bound Field Components?
https://tanstack.com/form/latest/docs/framework/react/guides/form-composition#pre-bound-field-components
This documentation suggests that pre-bound field components "infer" that such a field should assume that the value in the form state has the same type as the type argument to
useFieldContext
. However, this means that whenever I'm actually using the pre-bound field, there are no guardrails preventing me from using a pre-bound field with a form value of a different type.
Demonstrating in code, it seems like a big danger that I can do this:
Is this something I can actually assert? Or if not are there plans to get around it?Form Composition | TanStack Form React Docs
A common criticism of TanStack Form is its verbosity out-of-the-box. While this can be useful for educational purposes helping enforce understanding our APIs it's not ideal in production use cases. As...
22 Replies
like-gold•4mo ago
you can assert it if you make the component generic and pass the field for typing purposes
in this case you want to assert that
typeof field = { state: { value: string } }
exotic-emeraldOP•4mo ago
Yes, that's what I want to assert. Interesting... you mean like this?:
like-gold•4mo ago
or perhaps <field.String<typeof field> > works too. Haven‘t tried it before
but yes, for type important field components I do what you sent
exotic-emeraldOP•4mo ago
Got it. I wish this were somehow bound by default. I guess if I pass as a prop, then I don't need to use
useFieldContext
at all.
I don't want any of my pre-bound fields to be used without this type restriction
I'll do this for now though, thanks!like-gold•4mo ago
the context manages the 18 generics for you, which you wouldn‘t have with that prop I mentioned
exotic-emeraldOP•4mo ago
The typing comes out as
FieldApi<any, string, ActualTypeThatMatters, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any>
so I am not sure that it matters?
Yeah, actually not having much luck accomplishing the typing of such a prop
nvm got it, just had to make the key generic as well
fun!environmental-rose•4mo ago
The suggested fix to this problem is:
Even if
field.state.value
goes unused
That way String
is just defined as:
exotic-emeraldOP•3mo ago
Ah, that's a bit cleaner. I'm not encountering any real issue with passing the field reference
environmental-rose•3mo ago
Yet. 😉
We do not assure the consistency of generics in our code. We may add or remove many in the future
In even patch versions of the library
optimistic-gold•3mo ago
If I keep updating the generics to match the library, is there any risk to using the field reference approach?
It feels very clean
Better yet, is it possible that a future version of the library itself exports a TanstackField<TData> equivalent type? 😁 😁 😁
environmental-rose•3mo ago
Nope!
It broadly goes against our philosophy of requiring generics for our core usage
There isn't, nah, just a game of cat and mouse with generics updates
And it becomes a major headache on our end to support the "why doesn't inheritance work when using this generic type" type of tickets.
After all, it's a limit from TS itself not to have partial inheritance - otherwise we would likely enable that API
optimistic-gold•3mo ago
I see! Though I don't fully understand the inheritance problem implications, I'm glad both approaches will remain viable. 😁
like-gold•3mo ago
if I understood it right, partial inheritance would be
* "The first generic parameter is given, infer the rest from the options"
While TypeScript currently either wants all the parameters, parameters with defaults or inferring all of them
optimistic-gold•3mo ago
What use-cases would that enable in practice? In my case, wanting reusable form field components, I only care about TData no? Others being any is fine
like-gold•3mo ago
Type safety through generics while not requiring the user to define all 18. You'd allow the first one to be manually set, and the rest would still have the ability to infer their values from the options
but as it is right now with TypeScript, you either define them all or infer all of them
which is essentially what you were asking for here. You want the first one to be set while preserving the behaviour of the others
optimistic-gold•3mo ago
I actually just meant the exact type alias I sent above! Just maintained by the library instead of me
"AnyFieldApi" already exists
I just meant a "AnyFieldApiWithData<T>" with any everywhere except TData haha
like-gold•3mo ago
useFieldContext
is already implemented
and accepts one optional generic
so yeah, if you want the single generic for type reasons, then what crutchcorn suggested also workscorrect-apricot•3mo ago
While I appreciate TanStack Form's type-safe and verbose approach, I feel these advantages are lost when using context composition APIs for complex forms, as everything tends to become any typed. This makes me wonder about the utility of the verbosity. The withForm HOC is an option, but it seems better suited for larger form sections rather than individual fields. I've also tried a helper type approach, but working with generics has proven too complex.
environmental-rose•3mo ago
We're working on a brand new API to address many of these concerns
environmental-rose•3mo ago
GitHub
feat(react-form): Add
withFormLens
by LeCarbonator · Pull Reques...This is not confirmed to be added. This is an opportunity to get feedback on this suggestion and/or implementation.
Todos
- [ ] Is this concept okay to begin with? It&#39;s more related to disc...
environmental-rose•3mo ago
Feedback welcome/encouraged
Get it in now before we go live 😄
correct-apricot•3mo ago
Didn't saw it coming, amazing!