# Types Directory TypeScript definitions matching backend Pydantic models. Type safety between frontend and backend. ## File Overview | File | Contents | |------|----------| | `game.ts` | GameState, PlayResult, decisions, outcomes | | `player.ts` | SbaPlayer, Lineup, LineupPlayerState | | `websocket.ts` | Socket event types (Client↔Server) | | `api.ts` | REST API request/response types | | `index.ts` | Re-exports all types | ## Critical Type Mappings ### Backend → Frontend | Backend (Python) | Frontend (TypeScript) | Notes | |-----------------|----------------------|-------| | `GameState` | `GameState` | game.ts:61 | | `LineupPlayerState` | `LineupPlayerState` | game.ts:44 | | `DefensiveDecision` | `DefensiveDecision` | game.ts:124 | | `OffensiveDecision` | `OffensiveDecision` | game.ts:136 | | `PlayResult` | `PlayResult` | game.ts:217 | | `Lineup` | `Lineup` | index.ts | ### Key Type Relationships ``` GameState ├── current_batter: LineupPlayerState ← Minimal, for wire transfer ├── current_pitcher: LineupPlayerState ├── on_first/second/third: LineupPlayerState | null └── pending_defensive_decision: DefensiveDecision | null Lineup (from lineup_data event) ├── lineup_id: number ← Matches LineupPlayerState.lineup_id ├── position: string ├── is_active: boolean └── player: SbaPlayer ← Full player data ├── id: number ├── name: string └── headshot: string ``` ### Why Two Player Types? **LineupPlayerState** (in GameState): - Sent on every state update (~10-50 times per game) - Minimal: lineup_id, position, batting_order - ~50 bytes per player **Lineup** (from lineup_data): - Sent once when joining game - Full data including nested player with name, headshot - ~500 bytes per player **Optimization**: Send minimal data frequently, full data once. ## Common Type Usage ### Accessing Player Data ```typescript // GameState gives you LineupPlayerState const batterState: LineupPlayerState = gameStore.currentBatter // Need to lookup full Lineup for player details const batterLineup: Lineup = gameStore.findPlayerInLineup(batterState.lineup_id) const name: string = batterLineup.player.name ``` ### Decision Types ```typescript // Defensive (fielding team) interface DefensiveDecision { infield_depth: 'infield_in' | 'normal' | 'corners_in' outfield_depth: 'normal' | 'shallow' hold_runners: number[] } // Offensive (batting team) interface OffensiveDecision { action: 'swing_away' | 'steal' | 'hit_and_run' | 'sac_bunt' | 'squeeze_bunt' steal_attempts: number[] } ``` ## Type Maintenance When backend Pydantic models change: 1. Update corresponding frontend type 2. Check all components using that type 3. Run `npm run type-check` to catch mismatches