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
21.44k stars 484 forks source link

[BUG]: drizzle-zod: documented usage generates type error with `exactOptionalPropertyTypes` #2550

Open igniscyan opened 4 days ago

igniscyan commented 4 days ago

What version of drizzle-orm are you using?

0.31.2

What version of drizzle-kit are you using?

0.22.7

Describe the Bug

Using drizzle-zod to generate an insertSchema, I am greeted with type errors when attempting to use the generated schemas as documented in the samples. The generated schema will raise the ESLint flag of exactOptionalPropertyTypes, with the full error of

  Overload 1 of 2, '(value: { id?: number | SQL<unknown> | Placeholder<string, any>; name?: string | SQL<unknown> | Placeholder<string, any> | null; email?: string | SQL<unknown> | Placeholder<...> | null; password?: string | ... 2 more ... | null; role?: "admin" | ... 3 more ... | null; createdAt?: Date | ... 2 more ... | null; updatedAt?: Date | ... 2 more ... | null; }): PgInsertBase<...>', gave the following error.
    Argument of type '{ name?: string | null | undefined; email?: string | null | undefined; password?: string | null | undefined; role?: "admin" | "user" | null | undefined; }' is not assignable to parameter of type '{ id?: number | SQL<unknown> | Placeholder<string, any>; name?: string | SQL<unknown> | Placeholder<string, any> | null; email?: string | SQL<unknown> | Placeholder<string, any> | null; password?: string | ... 2 more ... | null; role?: "admin" | ... 3 more ... | null; createdAt?: Date | ... 2 more ... | null; update...' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
      Types of property 'name' are incompatible.
        Type 'string | null | undefined' is not assignable to type 'string | SQL<unknown> | Placeholder<string, any> | null'.
          Type 'undefined' is not assignable to type 'string | SQL<unknown> | Placeholder<string, any> | null'.
  Overload 2 of 2, '(values: { id?: number | SQL<unknown> | Placeholder<string, any>; name?: string | SQL<unknown> | Placeholder<string, any> | null; email?: string | SQL<unknown> | Placeholder<...> | null; password?: string | ... 2 more ... | null; role?: "admin" | ... 3 more ... | null; createdAt?: Date | ... 2 more ... | null; updatedAt?: Date | ... 2 more ... | null; }[]): PgInsertBase<...>', gave the following error.
    Argument of type '{ name?: string | null | undefined; email?: string | null | undefined; password?: string | null | undefined; role?: "admin" | "user" | null | undefined; }' is not assignable to parameter of type '{ id?: number | SQL<unknown> | Placeholder<string, any>; name?: string | SQL<unknown> | Placeholder<string, any> | null; email?: string | SQL<unknown> | Placeholder<string, any> | null; password?: string | ... 2 more ... | null; role?: "admin" | ... 3 more ... | null; createdAt?: Date | ... 2 more ... | null; update...'.
      Type '{ name?: string | null | undefined; email?: string | null | undefined; password?: string | null | undefined; role?: "admin" | "user" | null | undefined; }' is missing the following properties from type '{ id?: number | SQL<unknown> | Placeholder<string, any>; name?: string | SQL<unknown> | Placeholder<string, any> | null; email?: string | SQL<unknown> | Placeholder<string, any> | null; password?: string | ... 2 more ... | null; role?: "admin" | ... 3 more ... | null; createdAt?: Date | ... 2 more ... | null; update...': length, pop, push, concat, and 35 more.

The application will work as expected, but this linting error is raised whenever using the methodology provided in the documentation. Example usage:

try {
      const createdBaby = await db.insert(babies).values(insertBabySchema.parse(request.body)).returning();
      console.log(createdBaby);
import { serial, boolean, pgTable } from "drizzle-orm/pg-core";
import { createInsertSchema } from "drizzle-zod";
import { z } from "zod"; 

export const babies = pgTable("babies", { 
  id: serial("id").primaryKey(),
  isBaby: boolean("is_baby").notNull(),
})

export const insertBabySchema = createInsertSchema(babies);

Excuse the funny schema, just was done for testing purposes. Is there something I'm missing here? If so, it should likely be documented in the example usage.

Expected behavior

An error should not be raised.

Environment & setup

Using Neon Postgres, Drizzle, Drizzle-kit, and Fastify.