Drizzle produces wrong branded type using Zod

It appears using brands with Drizzle Zod doesn't work correct?
//? Files *//
const fileIdSchema = z.string().uuid().brand<'FileId'>()
type FileId = z.infer<typeof fileIdSchema>
export const files = pgTable('files', {
id: uuid()
.primaryKey()
.$defaultFn(() => uuidv7())
.$type<FileId>(),
name: varchar({ length: 255 }).notNull(),

})
//? Files *//
const fileIdSchema = z.string().uuid().brand<'FileId'>()
type FileId = z.infer<typeof fileIdSchema>
export const files = pgTable('files', {
id: uuid()
.primaryKey()
.$defaultFn(() => uuidv7())
.$type<FileId>(),
name: varchar({ length: 255 }).notNull(),

})
type fileInternal = typeof files.$inferSelect
type fileInternal = {
name: string;
id: string & BRAND<"FileId">;
....
}
type fileInternal = typeof files.$inferSelect
type fileInternal = {
name: string;
id: string & BRAND<"FileId">;
....
}
export const zodFilesInsertSchema = createInsertSchema(files)
export type FilesInsert = z.infer<typeof zodFilesInsertSchema>
type FilesInsert = {
name: string;
id: {
[x: number]: string;
length: number;
[Symbol.iterator]: {};
charAt: {};
...
[BRAND]: {
FileId: boolean;
};
} | undefined;

}
export const zodFilesInsertSchema = createInsertSchema(files)
export type FilesInsert = z.infer<typeof zodFilesInsertSchema>
type FilesInsert = {
name: string;
id: {
[x: number]: string;
length: number;
[Symbol.iterator]: {};
charAt: {};
...
[BRAND]: {
FileId: boolean;
};
} | undefined;

}
So effectively anytime you use your return value produced by db.insert().returning()and pass the ID field (branded) to another param that expects the branded FileId, you get an error like
Type '{ [x: number]: string; [BRAND]: { FileId: boolean; }; [Symbol.iterator]: {}; length: number; toString: {}; concat: {}; slice: {}; indexOf: {}; lastIndexOf: {}; includes: {}; at: {}; charAt: {}; charCodeAt: {}; ... 40 more ...; valueOf: {}; }' is not assignable to type 'string & BRAND<"FileId">'.
Type '{ [x: number]: string; [BRAND]: { FileId: boolean; }; [Symbol.iterator]: {}; length: number; toString: {}; concat: {}; slice: {}; indexOf: {}; lastIndexOf: {}; includes: {}; at: {}; charAt: {}; charCodeAt: {}; ... 40 more ...; valueOf: {}; }' is not assignable to type 'string'.
Type '{ [x: number]: string; [BRAND]: { FileId: boolean; }; [Symbol.iterator]: {}; length: number; toString: {}; concat: {}; slice: {}; indexOf: {}; lastIndexOf: {}; includes: {}; at: {}; charAt: {}; charCodeAt: {}; ... 40 more ...; valueOf: {}; }' is not assignable to type 'string & BRAND<"FileId">'.
Type '{ [x: number]: string; [BRAND]: { FileId: boolean; }; [Symbol.iterator]: {}; length: number; toString: {}; concat: {}; slice: {}; indexOf: {}; lastIndexOf: {}; includes: {}; at: {}; charAt: {}; charCodeAt: {}; ... 40 more ...; valueOf: {}; }' is not assignable to type 'string'.
4 Replies
DiamondDragon
DiamondDragonOP3w ago
I'm not sure what [BRAND]: { FileId: boolean; }; means and why its a boolean, or if the issue is the object is just totlaly different betwen what is expected , where the entire object just doesnt match
Mario564
Mario5642w ago
It seems there's an issue with branded schemas. Could you file a GH issue with the same info as above so we can keep track of it?
DiamondDragon
DiamondDragonOP2w ago
GitHub
[BUG]:Branded Zod Types Not Working As Expected · Issue #3834 · dri...
Report hasn't been filed before. I have verified that the bug I'm about to report hasn't been filed before. What version of drizzle-orm are you using? 0.38.2 What version of drizzle-kit...
Mario564
Mario5642w ago
Thanks And happy holidays to you too :)

Did you find this page helpful?