Skip to content

fix(drizzle-zod): fix coerce schema input types and inverted integer condition for Zod 4#5675

Open
DORI2001 wants to merge 2 commits intodrizzle-team:mainfrom
DORI2001:fix/drizzle-zod-coerce-types
Open

fix(drizzle-zod): fix coerce schema input types and inverted integer condition for Zod 4#5675
DORI2001 wants to merge 2 commits intodrizzle-team:mainfrom
DORI2001:fix/drizzle-zod-coerce-types

Conversation

@DORI2001
Copy link
Copy Markdown

@DORI2001 DORI2001 commented Apr 23, 2026

Problem

Closes #5659

When using createSchemaFactory({ coerce: true }) or createInsertSchema with coerce options in Zod 4, the TypeScript input types for coerced fields are unknown instead of the expected primitive types.

In Zod 4, z.coerce.boolean() and friends default their generic T to unknown, so z.input<typeof insertSchema> returns unknown for every coerced field.

There's also an inverted condition in numberColumnToSchema: .int() was being applied to non-integer columns and skipped for integer ones.

Fix

  1. Pass explicit generics to all z.coerce.*() calls so the input type is preserved:
    z.coerce.boolean<boolean>(), z.coerce.date<Date>(), z.coerce.number<number>(), z.coerce.bigint<bigint>(), z.coerce.string<string>()

  2. Fix the inverted integer condition in numberColumnToSchema:

    // before
    integer ? z.coerce.number() : z.coerce.number().int()
    // after
    integer ? z.coerce.number<number>().int() : z.coerce.number<number>()
  3. Update tests to assert correct input types on both createSelectSchema and createInsertSchema with coerce enabled.

…condition for Zod 4

In Zod 4, `z.coerce.*()` defaults its generic `T` to `unknown`, causing
`createInsertSchema` to infer `unknown` for all coerced fields instead of
the expected primitive types (boolean, number, string, bigint, Date).

Fix by passing explicit generics: `z.coerce.boolean<boolean>()`,
`z.coerce.number<number>()`, `z.coerce.date<Date>()`,
`z.coerce.bigint<bigint>()`, `z.coerce.string<string>()`.

Also fix an inverted condition in `numberColumnToSchema` where
`integer ? z.coerce.number() : z.coerce.number().int()` was applying
`.int()` to non-integer columns and omitting it for integer columns.

Closes drizzle-team#5659

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@shashwatpurplesectors
Copy link
Copy Markdown

this change is not not enough you will have to change the return types in column.type.ts as well.

The type-level definitions in column.types.ts also used the bare
z.coerce.ZodCoerced* interfaces, which default T to unknown.
Add explicit generics to match the runtime fix.
@DORI2001
Copy link
Copy Markdown
Author

Good catch — pushed an update that also adds the explicit generics to the type definitions in column.types.ts.

@shashwatpurplesectors
Copy link
Copy Markdown

cool. this should work now. hope it merges soon.

@DORI2001
Copy link
Copy Markdown
Author

DORI2001 commented May 2, 2026

@Sukairo-02 — gentle ping on this one! All CI checks are passing and a community member confirmed the fix looks correct. Happy to make any adjustments if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: unknown type for coerced fields in drizzle-zod in zod 4

2 participants