Refactoring TypeScript: Separating Business Logic from System Interactions
When refactoring code to separate concerns, read and follow the policy guide:
Policy: docs/policies/refactoring-typescript.md
When This Applies
- •Refactoring files that mix business logic with system calls (file I/O, HTTP, shell, DB)
- •Extracting interfaces from tightly coupled code
- •Creating
*.system.tswrappers for existing external dependencies - •Adding dependency injection to functions or classes that instantiate SDK clients
- •Writing mock implementations for newly extracted interfaces
- •Migrating from
mock.module()to interface-based DI - •Improving test coverage by making business logic testable
Refactoring Steps (Summary)
- •Identify system boundaries -- find mixed business logic + system calls
- •Define interface --
{domain}-interface.tswithI{Name}contract - •Create system implementation --
{domain}.system.ts, thin wrapper only - •Create mock implementation --
tests/mocks/{domain}-mock.ts - •Refactor business logic -- accept interface param with default value
- •Write tests -- use mock for fast, deterministic tests
- •Configure coverage -- add
**/*.system.tsto exclusion
Anti-Patterns to Flag
- •Business logic inside
*.system.tsfiles - •Overly broad interfaces combining multiple responsibilities
- •Direct dependency on concrete class instead of interface
- •Missing interface for external dependency
Read the full guide for code examples, common patterns (file system, shell, HTTP), and migration checklist.