The row object
At the heart of every table module is the row object:
export const row = z.object({ id: z.number().brand<"public.penguins.id">(), name: z.string(), species: z.string(), waddle_speed_kph: z.number(), favourite_snack: z.string().nullable(), date_of_birth: z.date(),});CREATE TABLE penguins ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, species TEXT NOT NULL, waddle_speed_kph NUMERIC NOT NULL, favourite_snack TEXT, -- Optional: not all penguins have refined palates. date_of_birth TIMESTAMP WITH TIME ZONE NOT NULL);The row serves 3 purposes:
-
Runtime validation
Every query that usessql.type(row)is validated at runtime. If Postgres returns data that doesn’t match this shape, you’ll find out immediately. -
Static typing
From this schema, we derive theRowtype:export type Row = z.infer<typeof row>; -
Query composition
The same schema is reused to derive column lists:export const columns = Object.keys(row.shape).map((col) =>sql.identifier([col]),);export const columnsFragment = sql.join(columns, sql.fragment`, `);You will see this used in lots of
no-orm’s queries.