Questions regarding migration to 1.x
Hello, I'm migrating from 0.35 to the latest.
In my react app, I have a lot of forms that are passed as props so I usually need to type them.
I used to do so with:
So that I could do:
But now that validators are gone and that FormApi seemingly changed, I'm struggling to find the correct way to get similar behavior.
The closest I could find by sheer trial and error is:
but it seems to cause problems and might not be the best.
For example if I want to have a component that can take any Form:
And then try to use it, I get:
The validator changes also seemed to break things, as I now get a type error whenever I have a form with default values and a schema with optional values, even when they should be/were compatible.
Sorry if this is a bit rambly but since this is so new I've had little chance to find answers/examples online ,especially as some of the official examples seem down.
24 Replies
mute-gold•6mo ago
My gut feeling says what you're looking for is the
withForm
HoC, that infers all the types for you. That way you don't have to define generics yourself. See example: https://tanstack.com/form/latest/docs/framework/react/guides/form-composition#breaking-big-forms-into-smaller-pieces
So basically it's implemented as a HoC so that it can infer the form-types for you, instead of you having to define the form type using generics yourself.afraid-scarletOP•6mo ago
Seems interesting, thanks, but I think that would mean rewriting a large portion of my app, i'm quite happy with my strongly typed generic so if I could just keep them it'd the best outcome.
rising-crimson•6mo ago
The generics have been completely rewritten in ~v0.42, so yes you will have to rewrite a bunch of stuff if you want to migrate to form composition API
afraid-scarletOP•6mo ago
Well I think buried under all of the new ones there is still one that represents a form, so then I only need to replace my old FormType with the new one in one place and I would be fine.
My problem is that I don't think I have a good way to know which one replaced it.
rising-crimson•6mo ago
The generics have decent naming, it should give you an idea of which parameters are which. Most of the new generics are related to validation, so if none of your fields handle that, you can pass
any
.
The main issue I see with keeping this passing structure is that you will unlikely be able to narrow the fields for type safety.
There's also helper types (AnyFormApi
and AnyFieldApi
) that are as wide as they can be.afraid-scarletOP•6mo ago
That is helpful thanks, do you know what generic hold the .Form and .Subscribe ?
Or something that combines the api with those.
There are so many generic that I'm kinda lost and just trying them randomly
rising-crimson•6mo ago
Sadly, I don't. I migrated from passing the Api directly as soon as the form composition beta came out
afraid-scarletOP•6mo ago
No problem, my best guess is still ReactFormExtendedApi, by typecasting I got around most of my problems.
The only really annoying one left is the zod validation .
rising-crimson•6mo ago
zod v3.24.0 implements standard schema, so you should be alright with upgrading that
afraid-scarletOP•6mo ago
That might just be it lol, i'm on 3.23 ...
rising-crimson•6mo ago
I upgraded from 3.22 no problem, so I assume you're fine
afraid-scarletOP•6mo ago
Yup that was it thanks, now I only have a
Type instantiation is excessively deep and possibly infinite.ts(2589)
on one of my components that takes 3 deep keys as props, which I guess is too much now.rising-crimson•6mo ago
it might just be an infer loop
give
NoInfer<T>
a tryafraid-scarletOP•6mo ago
Not sure how I would use that, seems to not exist on the tanstack form package itself ? It seems to only find it from tanstack query/table
rising-crimson•6mo ago
it's from typescript. What version of ts are you using?
tanstack v1.0 requires typescript v5.4+
afraid-scarletOP•6mo ago
I have 5.5.3
rising-crimson•6mo ago
yeah it's not imported then, it's part of typescript itself
afraid-scarletOP•6mo ago
I tried it on my DeepKey props to no avail, seems like a really cool thing to know though thanks
A bad workaround I've found is typing the form as Form<any> but I lose the deepkeys autocomplete
rising-crimson•6mo ago
you have an excessively deep instantiation because A infers from B which infers from A which infers from B which infers from A ...
it's the main issue with passing the generics directly as mentioned here
afraid-scarletOP•6mo ago
I would agree with you but it just happens in one use of the component, the others across the project being just fine
and also NoInfer didn't fix it
so might be something else
I stand corrected, seems like it happens in other uses my bad
Most of these disappeared with the zod update, but some still remain, and I'm truly puzzled.
mute-gold•6mo ago
It's likely because you're not explicitly typing the default values, so
PrioriteId
is being inferreed as being literally null (because without any external help TS has no way of knowing that PrioriteId
also can be a number, so it's being evaluated to always being null) .
You have to use zod.input
to infer the type based on your schema. This should solve it:
afraid-scarletOP•6mo ago
Thanks, is there another way to explicitely type the form without going through default values ? Might come handy.
I used to do it through the useForm hook, but that don't work anymore it seems
mute-gold•6mo ago
The fields are inferred from default values, as far as I know. If you dont want default values (not sure why?) you could cast I guess:
But based on experience it's a good idea always use default values. You can also define this elsewhere using the
formOptions
function. Then just pass the returnvalue of that into your form. something like this:
afraid-scarletOP•6mo ago
Thanks