End-to-end type safety with Zod, tRPC, Prisma, and TypeScript 5.7+ patterns. Use when creating Zod schemas, setting up tRPC, validating input, implementing exhaustive switch statements, branded types, or type checking with ty.
View on GitHubJanuary 25, 2026
Select agents to install to:
npx add-skill https://github.com/yonatangross/skillforge-claude-plugin/blob/main/skills/type-safety-validation/SKILL.md -a claude-code --skill type-safety-validationInstallation paths:
.claude/skills/type-safety-validation/# Type Safety & Validation
## Overview
**When to use this skill:**
- Building type-safe APIs (REST, RPC, GraphQL)
- Validating user input and external data
- Ensuring database queries are type-safe
- Creating end-to-end typed full-stack applications
- Implementing strict validation rules
## Core Stack Quick Reference
| Tool | Purpose | Key Pattern |
|------|---------|-------------|
| **Zod** | Runtime validation | `z.object({}).safeParse(data)` |
| **tRPC** | Type-safe APIs | `t.procedure.input(schema).query()` |
| **Prisma** | Type-safe ORM | Auto-generated types from schema |
| **TypeScript 5.7+** | Compile-time safety | `satisfies`, const params, decorators |
## Zod Essentials
```typescript
import { z } from 'zod'
// Define schema
const UserSchema = z.object({
id: z.string().uuid(),
email: z.string().email(),
age: z.number().int().positive().max(120),
role: z.enum(['admin', 'user', 'guest']),
createdAt: z.date().default(() => new Date())
})
// Infer TypeScript type
type User = z.infer<typeof UserSchema>
// Validate with error handling
const result = UserSchema.safeParse(data)
if (result.success) {
const user: User = result.data
} else {
console.error(result.error.issues)
}
```
**See:** `references/zod-patterns.md` for transforms, refinements, discriminated unions, and recursive types.
## tRPC Essentials
```typescript
import { initTRPC } from '@trpc/server'
import { z } from 'zod'
const t = initTRPC.create()
export const appRouter = t.router({
getUser: t.procedure
.input(z.object({ id: z.string() }))
.query(async ({ input }) => {
return await db.user.findUnique({ where: { id: input.id } })
}),
createUser: t.procedure
.input(z.object({ email: z.string().email(), name: z.string() }))
.mutation(async ({ input }) => {
return await db.user.create({ data: input })
})
})
export type AppRouter = typeof appRouter
```
**See:** `references/trpc-setup.md` for middleware, authentication, React integration,