TypeScript Development
Project Setup
Initialize with pnpm
pnpm init pnpm add -D typescript @types/node
TypeScript config
npx tsc --init
tsconfig.json
{ "compilerOptions": { "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true, "noUncheckedIndexedAccess": true, "noImplicitReturns": true, "esModuleInterop": true, "skipLibCheck": true, "outDir": "./dist" }, "include": ["src/**/*"] }
Type Patterns
Discriminated Unions
type Result<T> = | { success: true; data: T } | { success: false; error: Error };
function handleResult(result: Result<User>) { if (result.success) { console.log(result.data); // User } else { console.error(result.error); // Error } }
Branded Types
type UserId = string & { readonly brand: unique symbol }; type OrderId = string & { readonly brand: unique symbol };
function createUserId(id: string): UserId { return id as UserId; }
Utility Types
// Make all properties optional Partial<User>
// Make all properties required Required<User>
// Pick specific properties Pick<User, 'id' | 'email'>
// Omit specific properties Omit<User, 'password'>
// Make properties readonly Readonly<User>
Error Handling
// Result type pattern type Result<T, E = Error> = | { ok: true; value: T } | { ok: false; error: E };
async function fetchUser(id: string): Promise<Result<User>> { try { const user = await db.users.findById(id); if (!user) { return { ok: false, error: new Error('User not found') }; } return { ok: true, value: user }; } catch (error) { return { ok: false, error: error as Error }; } }
Testing with Vitest
import { describe, test, expect, vi } from 'vitest';
describe('UserService', () => { test('creates user with valid email', async () => { const service = new UserService(mockRepo); const user = await service.create('test@example.com'); expect(user.email).toBe('test@example.com'); });
test('throws on invalid email', async () => { const service = new UserService(mockRepo); await expect(service.create('invalid')).rejects.toThrow(); }); });
Tooling
Biome (linting + formatting)
pnpm add -D @biomejs/biome pnpm biome check --apply .
Vitest (testing)
pnpm add -D vitest pnpm vitest