Type Safety
End-to-end type safety with TypeScript, Prisma, and Next.js in the went framework.
TypeScript Configuration
The went framework comes with a pre-configured TypeScript setup optimized for Next.js 15:
{ "compilerOptions": { "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, "noEmit": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", "incremental": true, "plugins": [{ "name": "next" }], "baseUrl": ".", "paths": { "@/*": ["./src/*"] } } }
Database Type Safety with Prisma
Prisma automatically generates TypeScript types from your database schema:
import { PrismaClient, User, Order } from '@/generated/prisma' // TypeScript knows the exact shape of your data const user: User = await prisma.user.findUnique({ where: { id: 'user-id' } }) // Intellisense and type checking for all fields console.log(user.email) // ✅ TypeScript knows this exists console.log(user.invalid) // ❌ TypeScript error
Prisma provides type-safe database queries with full IntelliSense support:
// Type-safe queries with autocomplete const userWithOrders = await prisma.user.findMany({ where: { email: { contains: '@example.com' } // ✅ Valid // invalidField: 'value' // ❌ TypeScript error }, include: { orders: { where: { status: 'completed' } } } }) // Return type is automatically inferred // userWithOrders: (User & { orders: Order[] })[]
API Route Type Safety
The went framework provides full type safety for API routes through TypeScript integration with Next.js 15 App Router. All request and response types are properly typed, ensuring compile-time safety.
Route handlers automatically infer parameter types from dynamic routes, and Prisma integration ensures database operations are fully type-safe from the API layer through to the database schema.
Component Type Safety
Define strict interfaces for React component props:
// components/UserCard.tsx import { User } from '@/generated/prisma' interface UserCardProps { user: User onEdit?: (userId: string) => void showActions?: boolean } export function UserCard({ user, onEdit, showActions = true }: UserCardProps) { return ( <div className="card"> <h3>{user.email}</h3> {showActions && ( <button onClick={() => onEdit?.(user.id)}> Edit User </button> )} </div> ) }
Type-safe server components with async data fetching:
// app/users/page.tsx import { prisma } from '@/lib/db' import { UserCard } from '@/components/UserCard' interface PageProps { searchParams: { search?: string } } export default async function UsersPage({ searchParams }: PageProps) { const users = await prisma.user.findMany({ where: searchParams.search ? { email: { contains: searchParams.search } } : undefined }) return ( <div> {users.map(user => ( <UserCard key={user.id} user={user} /> ))} </div> ) }
Form Type Safety
Create type-safe form actions with validation:
// lib/actions.ts 'use server' import { z } from 'zod' import { prisma } from '@/lib/db' const CreateUserSchema = z.object({ email: z.string().email('Invalid email address') }) type CreateUserData = z.infer<typeof CreateUserSchema> export async function createUser(data: CreateUserData) { const validated = CreateUserSchema.parse(data) const user = await prisma.user.create({ data: { email: validated.email } }) return { success: true, user } } // Usage in component export function UserForm() { return ( <form action={createUser}> <input name="email" type="email" required /> <button type="submit">Create User</button> </form> ) }
Type Safety Best Practices
Strict TypeScript
- • Enable strict mode in tsconfig.json
- • Use noImplicitAny and noImplicitReturns
- • Avoid any type - use unknown instead
- • Enable exactOptionalPropertyTypes
Database Types
- • Use Prisma generated types everywhere
- • Run went db generate after schema changes
- • Use Prisma.UserSelect for partial selections
- • Leverage conditional types for includes
API Safety
- • Define request/response interfaces
- • Use zod for runtime validation
- • Type your server actions properly
- • Handle errors with typed responses
Development Workflow
- • Use TypeScript in strict mode
- • Set up ESLint with TypeScript rules
- • Run type checking in CI/CD pipeline
- • Use IDE with TypeScript support
Type Generation Commands
went db generate
Generate TypeScript types from Prisma schema
npm run build
Type check and build the application
npx tsc --noEmit
Type check without building (useful for CI)
Next Steps
Continue your journey with Went: