integration withs `drizzle-zod` breaks type-safe
Describe the bug
Im trying to use TanStack Form with shadcn, and I found this component https://fatahchan.github.io/shadcn-tanstack-form/ .
When using it, types generated by drizzle-zod looks weird in TanStack Form (check screenshot below).
I found out that this issue is not related to shadcn.
Meanwhile the model I defined is a bit complicated, so currently I have no idea whether the issue is actually with drizzle-zod or with the complicated typing itself.
Your minimal, reproducible example
https://codesandbox.io/p/github/TheOrdinaryWow/whispering-smoke/main
Steps to reproduce
- Full code suppied on TheOrdinaryWow/whispering-smoke Jump in and err error.
Expected behavior
Everything works good.
How often does this bug happen?
None
Screenshots or Videos
Platform
- OS: macOS
- Browser: Safari
- Version: 18.5 (20621.2.5.11.8)
TanStack Form adapter
react-form
TanStack Form version
1.12.3
TypeScript version
v5.8.3
Additional context
No response
The reason is because defaultValues is hardcoded as {}. Compare that to the actual type your schema wishes for, which is z.input<typeof lotteryInsertSchema>:
{
title: string;
prizes: LotteryPrize;
metadata: LotteryMetadata;
id?: number | undefined;
description?: string | undefined;
result?: LotteryResult | null | undefined;
status?: LotteryStatus | undefined;
}
You need to specify that your form uses the schema input type for default values
Also a related issue worth reading #1579
Also a related issue worth reading #1579
But it seems quite weird that same issue occurs using drizzle-arktype.
Also a related issue worth reading #1579
But it seems quite weird that same issue occurs using
drizzle-arktype.
They both implement Standard Schema which is what TSF supports. So it's actually expected to have similar behaviour.
Also a related issue worth reading #1579
But it seems quite weird that same issue occurs using
drizzle-arktype.They both implement Standard Schema which is what TSF supports. So it's actually expected to have similar behaviour.
const formSchema = z.object({
initiator_user_id: z.number().int(),
title: z.string().min(1).max(255),
description: z.string().max(1000).optional(),
prizes: z.object({
name: z.string().min(1).max(127),
description: z.string().max(255).optional(),
quantity: z.number().int().min(1),
content: z.array(z.string()).optional(),
}),
metadata: z.object({
preconditions: z.array(
z.union([
z.object({
type: z.literal("in_chat"),
chat_id: z.number().int(),
}),
z.object({
type: z.literal("uid_less_than"),
user_id: z.number().int(),
}),
]),
),
}),
});
this object gives invalid output as well, but without default values. How would it happen?
The reason is because
defaultValuesis hardcoded as{}. Compare that to the actual type your schema wishes for, which isz.input<typeof lotteryInsertSchema>:{ title: string; prizes: LotteryPrize; metadata: LotteryMetadata; id?: number | undefined; description?: string | undefined; result?: LotteryResult | null | undefined; status?: LotteryStatus | undefined; } You need to specify that your form uses the schema input type for default values
This is illogical, the default value is just the form's default value, and the validation schema handles the data the user submit.
@zicjin You're welcome to suggest what the typing should look like. The main concerns are:
- A user shouldn't be able to lock their form state accidentally by adding new properties to the schema
- A user may want null or undefined as starting value, while the schema only accepts its own value.
- A user may opt out of the standard schema, relying only on manual / no validation and
defaultValues
There have been other discussions related to this, even a suggestion for opening a PR. However, it has been a few months, so it's likely that the draft never went anywhere.