Skip to content

Validations with Zod

Once you have declared your schema you can access the corresponding Zod schema for it.

The Zod schema will not only take into account:

  • Type of the column.
  • Nullability.
  • Specific column data type validations that match validations at database level. For example, the range of an integer is: -2147483648 to +2147483647.

The schema will also reject explicit undefined values when parsing.

You can read more about the specific validations for each column data type in the Column Types API

Retrieving the Zod schema

Zod schemas are made available through the zodSchema function from @monolayer/pg/zod.

ts
const users = table({
  columns: {
    id: integer().generatedAlwaysAsIdentity(),
    name: text(),
    createdAt: timestampWithTimeZone().default(sql`now`).notNull(),
  },
  constraints: {
    primaryKey: primaryKey(["id"]),
  },
});

const usersZodSchema = zodSchema(users);

Schema Types

Each column has a TypeScript type for input and output values (parsed) in the schema. The output values match the select type for the column(except bytea columns *)

(*) Since Buffer is a Node.js API, the schema will not coerce the input to Buffer for browser compatibility. The output type will be the same as the input type.

ColumnInputOutput
bigint  bigint | number | string    string   
bigserial  bigint | number | string    string  
bit  string    string  
bitVarying  string    string  
boolean  boolean | Boolish*    boolean  
bytea  Buffer | string    Buffer | string  
characterVarying  string    string  
character  string    string  
cidr  string    string  
date  Date | string    Date  
doublePrecision  bigint | number | string    string  
enumerated  enum values    enum values  
inet  string    string  
integer  number | string    number  
json  JsonValue*    JsonValue*  
jsonb  JsonValue*    JsonValue*  
macaddr  string    string  
macaddr8  string    string  
numeric  bigint | number | string    number  
real  bigint | number | string    string  
serial  number | string    number  
smallint  number | string    number  
time  string    string  
timeWithTimeZone  string    string  
timestamp  Date | string    Date  
timestampWithTimeZone  Date | string    Date  
tsquery  string    string  
tsvector  string    string  
uuid  string    string  
xml  string    string  

(*) Boolish and JsonValue are defined as follows:

ts
type Boolish = "true" | "false" | "yes" | "no" | 1 | 0 | "1" | "0" | "on" | "off";
type JsonArray = JsonValue[];
type JsonValue = boolean | number | string | Record<string, unknown> | JsonArray;

Example

ts
const userRole = enumType("user_role", ["admin", "user"]);
const users = table({
  columns: {
    id: integer().generatedAlwaysAsIdentity(),
    name: text(),
    role: enumerated(userRole).notNull(),
    orderCount: integer().notNull().default(0),
    createdAt: timestampWithTimeZone().default(sql`now`).notNull(),
  },
  constraints: {
    primaryKey: primaryKey(["id"]),
  },
});
const schema = zodSchema(users);
type InputType = z.input<typeof schema>;
type OutputType = z.output<typeof schema>;

InputType will be:

ts
type InputType = {
  id: never;
  name?: string | null | undefined;
  role: "user" | "admin";
  orderCount: number | string | undefined;
  createdAt?: Date | string | undefined;
}

OutputType will be:

ts
type OutputType = {
  id: never;
  name?: string | null | undefined;
  orderCount?: number | undefined;
  role: "user" | "admin";
  createdAt?: Date | undefined;
}