How do I type my form if I need to pass it to other components?
Before in 0.40 I was doing:
`
But now that doesn't work and I don't want to have to type every single type of the 10 types FormApi requires... If it can be avoided
41 Replies
extended-salmonOP•7mo ago
literally just read the post below this
my bad
sorry
let me close it
old-apricot•7mo ago
You want to use our upcoming API for withForm:
https://github.com/TanStack/form/pull/1179
GitHub
[WIP] Reusable app hook by crutchcorn · Pull Request #1179 · TanSta...
This has been cooking in the oven for a long time - I'm extremely sorry it took me so long to figure out the direction we wanted to go in.
This PR introduces three new APIs to help with:
...
old-apricot•7mo ago
Oh lol you good
extended-salmonOP•7mo ago
The other guy's title is very bad in my defense
XD
@crutchcorn is the API released? What do I do in the mean time?
robust-apricot•7mo ago
the api is marked as draft, but I can confirm that it is useable in its current state
old-apricot•7mo ago
API isn't released, but it should be stable. We're just waiting on docs and final community feedback
So you can use that PR version of you'd like for sure, but there's also nothing wrong with staying at 0.44 (was it?) and upgrading once we merge
extended-salmonOP•7mo ago
Ok I can I do that then. Thank you!
While I have you one quick question. Is there a way I can set the entire form? Like setFieldValue but for the entire form
@crutchcorn
old-apricot•7mo ago
That would be tricky for us. There's not. What are you trying to do?
extended-salmonOP•7mo ago
Well, I'm trying to hack a solution to a bug report I submitted: https://github.com/TanStack/form/issues/1171
Its blocking an important feature so I was thinking of trying to set all the form values instead of the array or index value and see if that worked. I can confirm it doesn't, I found out you can use reset to set all the field values but it still same behaviour
GitHub
Removal of objects from nested arrays doesn't work as expected · Is...
Describe the bug When removing an object from a nested array only the "id" field is removed from the element. This happens both if you use arrayField.removeValue and form.setFieldValue. Y...
old-apricot•7mo ago
@Leonardo wanna look into the
removal of objects from nested arrays
issue?extended-salmonOP•7mo ago
it seems to be an error with whatever you are doing to reconcile the original structure and the new one that overrides it
robust-apricot•7mo ago
this might explain a bug we‘ve encountered before when calling
swapValues
I might take a look at it tomorrow, perhaps it‘s something that can be fixed in a few lines
the bug was about swapping two objects of different kinds and failing at runtimeextended-salmonOP•7mo ago
It might be related you are right. Its definitely something wrong in the process that merges the old form values and the new form values. Because the bug appears if you do any of:
- arrayField.removeValue()
- arrayField.setValue() -> not sure if this is the api but I mean setting the entire array with the filtered item removed
- parentFieldOfArray.setValue() -> same as above
- form.reset(entireFormValuesWithFilteredItem)
robust-apricot•7mo ago
what about a callback function as updater? instead of passing an array, pass
(inputArray) => newArray
to the method
have you given that a try?extended-salmonOP•7mo ago
No I haven't but give me a second and I can!
Yes same issue
Yep Same issue with this code:
robust-apricot•7mo ago
:HmmNotes:
extended-salmonOP•7mo ago
😂
Oh man, this bug is really killing me. But I got more information for you @Luca | LeCarbonator I would have to verify it with a minimal example but it appears that if you set the entire array with objects that are very different there is no issue. Exactly what that means I would need to do more testing
robust-apricot•7mo ago
not sure what you mean. Like creating a whole new array instead of shallow copying the first one?
that could help, actually. Maybe the object reference is the breaking part
your example seems a bit iffy. You have a Field with the state value, but access the state from the form level instead
robust-apricot•7mo ago
https://stackblitz.com/edit/tanstack-form-6yjqax4x?file=src%2Fminimal.tsx consider this fork
LeCarbonator
StackBlitz
Removal of objects from nested arrays doesn't work as expected (for...
Run official live example code for Form Simple, created by Tanstack on StackBlitz
robust-apricot•7mo ago
oh dear, I broke something :KEKWait:
there we go
something I've yet to figure out is why passing
item.id
as key crashes it on click, while itemIndex
is validextended-salmonOP•7mo ago
Because somehow it generates objects without the index
Like instead of removing the item it first removes it then on a rerun it adds it back again with id missing
extended-salmonOP•7mo ago
Look at these logs:
- The top one first component render (not like initial just in response to an action)
- The bot one is the component rerenders and you can see that the library added back in a bunch of weird objects with key values that probably correspond to some of the objects that were removed

extended-salmonOP•6mo ago
If you need I'm happy to jump on a call and explain further
@crutchcorn I am reading through the docs on the form composition and I must be missing something because this is incredibly inconvenient.
If I am understanding it correctly. I need to define the form options outside of the component so I can import them into other components and spread them. But those options are not even used they are just for typesafety, so we have replaced typing a generic with having to import the form options everywhere and spreading them into the withForm HOC? We are creating a copy of the form options object for each sub component in the form just for type safety?
Also, I'm using react query mutations for the submission of my forms. Which means I have to do:
I'm going crazy, there is no way this is the recommended way of doing things. Having to duplicate parameters like this seems awful and super prone to error.
Then I have to continue this pattern of giving bogus inputs and typecasting them to something else to actually get the typesafety I want. For example:
I hope I am not sounding in any way rude. I just can't believe this would be the recommended approach
old-apricot•6mo ago
I'm going crazy, there is no way this is the recommended way of doing things.
I just can't believe this would be the recommended approach
I hope I am not sounding in any way rude.If you can think of alternative ways to do things without requiring a generic passed anywhere and still inferring all 9 values in
withForm
, lmk
Until then, see aboverobust-apricot•6mo ago
the withForm looks about right, though you have an unnecessary
as unknown
in there. If you set an initial value of []
instead of ““
TS probably wouldn‘t complaincorrect-apricot•6mo ago
just create another function that will return form, after that type
ReturnType<typeof getForm>
where getForm is the functino that creates the form. I am currently doing this and it works perfectly finerobust-apricot•6mo ago
do you have an example?
correct-apricot•6mo ago

correct-apricot•6mo ago

correct-apricot•6mo ago

correct-apricot•6mo ago

noble-gold•6mo ago
Curious if there’s issues using this. This is actually more typesafe atm due to this bug https://github.com/TanStack/form/issues/1273
seems a lot easier than having to use the HOC and formOptions
GitHub
Missing type inference with Validators in formOptions · Issue #1273...
Describe the bug Currently, defining validators within the formOptions function does not allow proper type inference from defaultOptions. To retain type inference, users are forced to define valida...
extended-salmonOP•6mo ago
After migrating a significant portion of the codebase to this new pattern I will say that it is not as bad as I thought initially. Its quite a bit more verbose than I would like but it works fine.
I think the worse part is the withForm HOC. Its really ugly (IMHO) to have to proxy the types for the additional props in such a way. Also really it is infering the type from the form options which will not contain the complete form type in most cases since you most likely do something like this:
Which doesn't feel great. In the end anywhere you use the withForm HOC you are just infering the types based on the formOptions in a, arguably, more verbose and unintuitive way than doing something like:
I'm not a ts wizard but I cannot see any benefit to the HOC over doing something like this.
@Choco Unfortunaly, for me this is also a lot of work for me since building my form has a lot of dependencies. But I think it is still less work than wiring all the HOC's
And it seems to work with useAppForm also
noble-gold•6mo ago
Curious what you mean by this? I don't understand why adding 1 hook would cause issues? What do you mean by dependencies?
extended-salmonOP•6mo ago
Its not that big of an issue, its just that I have to pass a lot of stuff to the hook (i.e it needs to take like 5+ params instead of 0) so it's a little annoying. But it works well I have refactored everything with this approach and it is much nicer than the proposed approach
noble-gold•6mo ago
Nice, yeah that makes sense if your formOptions do require parameterized values
genetic-orange•6mo ago
Honestly I would happily have an API that takes 20+ Generics if it meant I could wrap that for my own internal use and get type safety back
I suppose I could do this in userland and just not have type safety INSIDE of my solution
correct-apricot•6mo ago
Right now I’m working around it by any-casting the passed form into the
withForm
components and making the forms own defaulValues
by combining the child/sub forms formOptions.
That way, at least the partials are internally typed and the form takes the types from them.
To make subforms I take an extra name prop and use use an extra function getName(name: typeof formOpts.defaultValues): any
to make the AppFields names inside. Again, that at least gives internal safety as long as the function is used.
I do have sone ideas I want to try to get something mire integrated for that but believe that they all depend in first solving the issues with passing extending forms without any.noble-gold•6mo ago
Important to note inference doesn’t ONLY come from the default values. Also from the validators and listeners(coming soon I think).
So doing those strategies may work but runtime may differ from the types that are inferred. Which is why @Choco ‘s suggestion is technically more typesafe since you’re inferring everything
noble-gold•6mo ago
GitHub
formOptions missing type inference leads to incorrect inferred type...
Describe the bug Currently, defining validators within the formOptions function does not allow proper type inference from defaultOptions. To retain type inference, users are forced to define valida...
correct-apricot•6mo ago
Hmm, I'll have to try that.
I consider my current "solution" to be more as a temporary workaround to something I expect (or at least hope) to be enabled in a similar way without it soon-ish. The way I see it, its mostly just that strange reverse typing thing going on with passing extending forms to
withForm
components holding things back - which technically isn't even exclusive to withForm
, it would happen all the same with manually typed FormApis.
Once that is solved, I'd like to think that adding some sort of subform selector should be much more straightforward.
Besides, I kind of ended up mostly putting validators on the AppFields anyways 😄
Might not be the best way but it works quite nicely with what I'm doing right now.