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.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.