Branded primary keys
Notice the id column:
id: z.number().brand<"public.penguins.id">(),This uses Zod branding to create a nominal type for your primary key.
What does that give you?
Section titled “What does that give you?”export type Id = Row["id"];Now Id is not just a number. TypeScript will treat it as a distinct type:
function getPenguin(id: Id) {}function getZoo(id: ZooId) {}
getPenguin(zooId); // Compilation error.Why this is useful
Section titled “Why this is useful”The goal is to catch situations like this at compile time:
- Passing the ID variable as an argument to the wrong table.
- Passing user input where a database ID is expected.
- Using raw numbers instead of validated identifiers.
Foreign Keys
Section titled “Foreign Keys”If a table contains a foreign key reference, this is also branded on your row object.
export const row = z.object({ id: z.number().brand<"public.flight_attempts.id">(), penguin: z.number().brand<"public.penguins.id">(), // ...});