TypeScript issue if the (zod) schema is a union or is using superRefine?
Hi,
I created a minimal reproducible example of a ecommerce form I am working on: https://github.com/thobas-dnvgl/tanstack-demo
The ieda is to ask for the mailing address and have a choice (off by default) to enter another address for the billing address.
I thought about using a discriminated union but I get a TypeScript error. I then used
.superRefine
but I still get a TypeScript error (all of that is documented in the README in the repository). The form works as expected and the error disappears if I do not use satisfies TypeData
on the defautlValues
but it's less type safe.
Any idea what's going on? Bug in TanStrack Form? Zod schema that could be improved?
Thanks!GitHub
GitHub - thobas-dnvgl/tanstack-demo: TanStack Form demo with zod an...
TanStack Form demo with zod and radio buttons (yes the name of the repo could have been better) - thobas-dnvgl/tanstack-demo
5 Replies
conscious-sapphire•4mo ago
Hi!
Tanstack form uses the input type from standard schemas. Zod implements this by using the type
z.input<typeof yourSchema>
.
Your code appears to be using z.infer
which will create the wrong type.
As for the defaultValues
, instead of satisfying TypeData
, you can cast it as TypeData
straight away like so:
Let me know if the fix above solved your issue.
A note for future schemas: zod unions will need to be exhaustive. Zod is strict with passthrough properties, but your form will always
have some value in the conditional properties. Widen the restriction to let it pass through.
sunny-greenOP•4mo ago
Thanks, I've used
satisfies
because I remembered a PR switching from it in the docs but it looks like it was reverted to casting like your suggest so I will use that.
As far as I can tell, the union I tried (and tried again) is exhaustive?
I still get:
But now I have an alternative. 🙂conscious-sapphire•4mo ago
strange ... I'll boot up a stackblitz version of this repro later so it's quicker to test.
Is it alright if I copy the code?
sunny-greenOP•4mo ago
of course, this repository is not a real app. it's a minimum viable example and has been made for experiments like these 🙂
conscious-sapphire•4mo ago
How strange ... It seems like TypeScript is getting confused with the union and tries to 'resolve' it before it even compares with the schema.
It might be type narrowing (TypeScript infers that
defaultValues
will never have separateBillingAddress: true
before being passed to the hook and therefore is only one of the two possible unions). But I don't understand why that's causing trouble