zod
Create and modify Zod schemas for runtime validation with proper type inference.
SKILL.md.claude/skills/zod/SKILL.md
GitHubDefine schemas with specificity: Prefer concrete schema methods over loose ones.
- Use
z.string().min(1)instead of barez.string()for required non-empty strings - Use
z.number().int().nonnegative()instead of barez.number()when appropriate - Use
z.enum()for known string unions - Use
z.literal()for exact values
- Use
Derive types from schemas: Always use
z.infer<typeof Schema>to derive TypeScript types from Zod schemas. Do not define the type separately and the schema separately — the schema is the source of truth.const MySchema = z.object({ name: z.string().min(1), count: z.number().int().nonnegative(), }); type My = z.infer<typeof MySchema>;Choose the right parse method:
.safeParse()for external or untrusted input (API payloads, user input, parsed documents) — check.successbefore using.data.parse()for internal guaranteed data where a thrown error indicates a programming bug
Colocate schema with type: Place the Zod schema in the same file as the type it defines. Export both the schema and the inferred type.
Test stubs: Use
zockerwithcreateStubFromSchema()from@carrot-fndn/shared/testingto generate test data from schemas. This ensures stubs always match the schema definition.Schema composition: Use
.extend(),.merge(),.pick(),.omit(), and.partial()to compose schemas from existing ones rather than duplicating field definitions.Optional fields: Use
z.optional()or.optional()for truly optional fields. Remember thatexactOptionalPropertyTypesis enabled in tsconfig, so optional fields must be explicitly marked.Const-object +
z.enum()pattern: For value sets, define a const object mapping human-readable keys to values, then derive az.enum()using theObject.valuestuple cast. Use.extract()or.literal()to narrow for deeper schema layers.const DOCUMENT_CATEGORY = { Methodology: 'methodology', Audit: 'audit', Certificate: 'certificate', } as const; const DocumentCategorySchema = z.enum( Object.values(DOCUMENT_CATEGORY) as [string, ...string[]], ); // Narrower schema for a specific layer const AuditOnlySchema = DocumentCategorySchema.extract(['audit']); const MethodologyLiteralSchema = z.literal(DOCUMENT_CATEGORY.Methodology);