# 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
