© 2026 Hedgehog Software, LLC

TwitterGitHubDiscord
More
CommunitiesDocsAboutTermsPrivacy
Search
Star
Setup for Free
Drizzle TeamDT
Drizzle Team•3y ago•
2 replies
philbookst

Problem with infering json type in zod schema

When using the following table/schema:
const Test = mysqlTable(
    "Test",
    {
        id: serial("id").primaryKey().notNull(),
        value: json("value").$type<{ a: string, b: number }>().notNull()
    },
)
        
const TestInsertSchema = createInsertSchema(Test)

const ValueFromSchema = TestInsertSchema.pick({
    value: true
})

type Value = z.infer<typeof ValueFromSchema>
// Value is typed as following:
// type Value = {
//     value: ((string | number | boolean | {
//         [key: string]: Json;
//     } | Json[]) & (string | number | boolean | {
//         [key: string]: Json;
//     } | Json[] | undefined)) | null;
// }
const Test = mysqlTable(
    "Test",
    {
        id: serial("id").primaryKey().notNull(),
        value: json("value").$type<{ a: string, b: number }>().notNull()
    },
)
        
const TestInsertSchema = createInsertSchema(Test)

const ValueFromSchema = TestInsertSchema.pick({
    value: true
})

type Value = z.infer<typeof ValueFromSchema>
// Value is typed as following:
// type Value = {
//     value: ((string | number | boolean | {
//         [key: string]: Json;
//     } | Json[]) & (string | number | boolean | {
//         [key: string]: Json;
//     } | Json[] | undefined)) | null;
// }


Am I doing something wrong? How can I pick the value key with correct types from the schema?
Solution
The
.$type()
.$type()
helper only works on the type level, it cannot change the runtime behavior. The schema validation happens at runtime, thus it doesn't know about your type. If you want to validate your json field according to your type, you would need to refine the insert schema, like this:
const TestInsertSchema = createInsertSchema, {
  value: () => z.object({ a: z.string(), b: z.number() }),
});
const TestInsertSchema = createInsertSchema, {
  value: () => z.object({ a: z.string(), b: z.number() }),
});


To make it a bit more convenient, you can extract the object schema into a variable and reuse it:

const valueSchema = z.object({ a: z.string(), b: z.number() });

const Test = mysqlTable(
    "Test",
    {
        id: serial("id").primaryKey().notNull(),
        value: json("value").$type<z.infer<typeof valueSchema>>().notNull()
    },
);

const TestInsertSchema = createInsertSchema, {
  value: () => valueSchema,
});
const valueSchema = z.object({ a: z.string(), b: z.number() });

const Test = mysqlTable(
    "Test",
    {
        id: serial("id").primaryKey().notNull(),
        value: json("value").$type<z.infer<typeof valueSchema>>().notNull()
    },
);

const TestInsertSchema = createInsertSchema, {
  value: () => valueSchema,
});
Jump to solution
Drizzle TeamJoin
The official Discord for all Drizzle related projects, such as Drizzle ORM, Drizzle Kit, Drizzle Studio and more!
11,879Members
Resources
Was this page helpful?

Similar Threads

Recent Announcements

Similar Threads

drizzle-zod not infering jsonb type properly
Drizzle TeamDTDrizzle Team / help
2y ago
Issue with sqlite real type and drizzle-zod schema
Drizzle TeamDTDrizzle Team / help
4mo ago
Unifying a JSON column's return type with `drizzle-zod`'s `Json`
Drizzle TeamDTDrizzle Team / help
2y ago
drizzle-zod insert/update schema refinements type
Drizzle TeamDTDrizzle Team / help
11mo ago