Skip to main content

Advanced Types & Schemas

Prisma Guard does not just generate simple validation schemas; it exports a highly ergonomic suite of TypeScript types and schema variants to fit the full lifecycle of your application.


Dual Schema Design

By default, unless configured with skipScalar: true, Prisma Guard generates two schema variants for every Prisma model:

  1. Public Schemas (UserCreateSchema): Respects global and field-level omissions (like zodOmit in configuration, @zod.omit comment decorators, and @zod.pick). This is perfect for parsing client requests at your API boundary.
  2. Scalar Schemas (UserCreateScalarSchema): Bypasses all omission rules, retaining every single field defined in the database schema. This is perfect for internal database operations and background queues.

Exported Types Reference

For a model named Service, the following TypeScript types are automatically generated and exported:

TypeTarget SchemaDescription
ServiceCreateServiceCreateSchemaThe standard output type representing a validated public payload.
ServiceInputServiceCreateSchemaThe input type (before Zod coercion and default evaluation).
ServiceUpdateServiceUpdateSchemaPartial variant representing patch payloads for public update operations.
ServiceScalarServiceCreateScalarSchemaThe full database record including omitted fields (like secrets/keys).
ServiceScalarInputServiceCreateScalarSchemaThe raw input structure for database-complete operations.
ServiceScalarUpdateServiceUpdateScalarSchemaPartial variant for internal database updates.
ServiceCreateRequiredSpecial mappingThe ultimate service type. It skips system-controlled fields (like id or timestamps) while requiring all internal fields (like database tenant references).

skipScalar Configuration Comparison

If you want to keep output file sizes minimal and do not require separate database-complete schemas, you can enable skipScalar in your configuration:

Option A: skipScalar: false (Default)

The generator creates both Public and Scalar schemas:

// generated/zod/service.ts
import { z } from "zod";

// 1. Public Schema (respects omissions)
export const ServiceCreateSchema = z.object({
name: z.string().trim().min(1),
// 'secretApiKey' and 'tenantId' are omitted from the public schema
});

export const ServiceUpdateSchema = ServiceCreateSchema.partial();

// 2. Scalar Schema (ignores omissions, contains all database fields)
export const ServiceCreateScalarSchema = z.object({
id: z.string().trim().min(1),
name: z.string().trim().min(1),
secretApiKey: z.string().trim().min(1),
tenantId: z.string().trim().min(1),
createdAt: z.coerce.date(),
});

export const ServiceUpdateScalarSchema = ServiceCreateScalarSchema.partial();

// Exports all 7 types (ServiceCreate, ServiceInput, ServiceUpdate, etc.)

Option B: skipScalar: true

Only public schemas are generated, reducing boilerplate code:

// generated/zod/service.ts
import { z } from "zod";

// ONLY Public Schemas are generated
export const ServiceCreateSchema = z.object({
name: z.string().trim().min(1),
});

export const ServiceUpdateSchema = ServiceCreateSchema.partial();

// NO Scalar schemas or Scalar/Required types are generated.
// Exports ONLY 3 base types (ServiceCreate, ServiceInput, ServiceUpdate).

Recommendation: Internal Service Layer Architecture

[!TIP] When defining internal service operations (e.g. createService(data: ServiceCreateRequired)), prefer utilizing the ModelCreateRequired type.

Using this type ensures:

  • Auto-generated fields (like id, createdAt, or updatedAt) remain optional so you don't have to mock them.
  • Internally required fields (such as tenantId or sensitive metadata) remain required, preventing runtime bugs when invoking internal helper methods.