drizzle-team / drizzle-orm

Headless TypeScript ORM with a head. Runs on Node, Bun and Deno. Lives on the Edge and yes, it's a JavaScript ORM too 😅
https://orm.drizzle.team
Apache License 2.0
24.47k stars 643 forks source link

[BUG]: drizzle-zod doesn't respect `.json().$type<>()` #2855

Open dmythro opened 2 months ago

dmythro commented 2 months ago

What version of drizzle-orm are you using?

0.33.0

What version of drizzle-kit are you using?

0.24.2

Describe the Bug

When I create a JSON field like this field1: json('field1').$type<string[]>().notNull().default([]) and create a Zod schema from that table with createInsertSchema(), I get errors on data types when I parse the schema into params from a request to insert it with Drizzle.

Example:

const someTable = pgTable('someTable', {
  field1: json('field1').$type<string[]>().notNull().default([]),
  // createdAt, updatedAt ...
})

const someThingSchema = createInsertSchema(someTable)
  .omit({ createdAt: true, updatedAt: true })
  .partial()

/// ..

const params = someThingSchema.parse(await request.json())
const [item] = await drizzleDbInstance.insert(someTable).values(params).returning()`

I get typing errors which breaks the build and I have to manually cast the proper type inferred from the table schema again. And same happens with custom types as well. Removing .partial() doesn't really affect the result.

...
      Types of property 'field1' are incompatible.
        Type 'Json | undefined' is not assignable to type 'string[] | SQL<unknown> | Placeholder<string, any> | undefined'.
          Type 'null' is not assignable to type 'string[] | SQL<unknown> | Placeholder<string, any> | undefined'.

Expected behavior

I expect JSON data types are properly inferred from the schema definition. Maybe I misuse something? I suppose there should also be something like createUpdateSchema maybe?

Environment & setup

"drizzle-zod": "0.5.1".

x0fma commented 2 months ago

You can use the second parameter refine of createInsertSchema function to specify your json structure once.

Something like createInsertSchema(someTable, { field1: z.array(z.string()) })

Hope this helps!

dmythro commented 2 months ago

You can use the second parameter refine of createInsertSchema function to specify your json structure once.

Something like createInsertSchema(someTable, { field1: z.array(z.string()) })

Hope this helps!

Thanks, but it doesn't help. I don't wanna specify same schema twice. The whole purpose of this is to generate Zod schema from the actual table schema, which is defined in a single place and all changes later are done in a one place as well without duplicating them for validation.