Problem
src/components/Farmhand/FarmhandReducers.tsx is a class that extends Component and contains 50+ stub methods that all throw "Unimplemented". At runtime, matching reducer functions replace these stubs. This pattern adds indirection, uses any[] for all method parameters, and has a TODO comment on line 31 that says: "TODO: Replace this with a TypeScript interface."
The current code:
export class FarmhandReducers extends Component<FarmhandProps, FarmhandState> {
addCowToInventory(...args: any[]) {
throw new Error("Unimplemented")
}
addPeer(...args: any[]) {
throw new Error("Unimplemented")
}
// ... 50+ more stub methods
}
Implementation Plan
Step 1: Define a ReducerMethods interface
Create an interface in src/components/Farmhand/FarmhandReducers.tsx that matches all 50+ reducer method signatures. Each reducer follows the pattern (state: farmhand.state, ...optionalArgs) => farmhand.state.
export interface ReducerMethods {
addCowToInventory: (state: farmhand.state) => farmhand.state
addPeer: (state: farmhand.state) => farmhand.state
adjustLoan: (state: farmhand.state, amount: number) => farmhand.state
changeCowAutomaticHugState: (state: farmhand.state, cowId: string, enabled: boolean) => farmhand.state
// ... all 50+ methods with correct signatures
}
To get the correct signatures, look at the reducer implementations in src/game-logic/reducers/. Each exported reducer function defines the parameter types.
Step 2: Create a bound reducers object
Instead of the class with stubs, create a plain object that maps method names to bound reducer functions:
import * as reducers from "../../game-logic/reducers/index.js"
export const reducerMethods: ReducerMethods = {
addCowToInventory: reducers.addCowToInventory.bind(null),
addPeer: reducers.addPeer.bind(null),
// ... all methods
}
Step 3: Update Farmhand component to use the interface directly
The Farmhand component (in src/components/Farmhand/Farmhand.tsx) uses useFarmhand hook which currently interacts with the FarmhandReducers class. Update the hook to work with the ReducerMethods interface directly.
Step 4: Remove the FarmhandReducers class
Delete the FarmhandReducers class entirely, keeping only the ReducerMethods interface and the bound object.
Step 5: Run type checker
Acceptance Criteria
ReducerMethods interface is defined with all 50+ method signatures matching the reducers in src/game-logic/reducers/
FarmhandReducers class is removed (no more stub methods with any[])
- All reducer methods are bound to the Farmhand instance via a plain object
- Zero
any[] parameter lists remain in the reducer binding code
npm run check:types passes with no errors
npm test passes
Problem
src/components/Farmhand/FarmhandReducers.tsxis a class that extendsComponentand contains 50+ stub methods that all throw "Unimplemented". At runtime, matching reducer functions replace these stubs. This pattern adds indirection, usesany[]for all method parameters, and has a TODO comment on line 31 that says: "TODO: Replace this with a TypeScript interface."The current code:
Implementation Plan
Step 1: Define a
ReducerMethodsinterfaceCreate an interface in
src/components/Farmhand/FarmhandReducers.tsxthat matches all 50+ reducer method signatures. Each reducer follows the pattern(state: farmhand.state, ...optionalArgs) => farmhand.state.To get the correct signatures, look at the reducer implementations in
src/game-logic/reducers/. Each exported reducer function defines the parameter types.Step 2: Create a bound reducers object
Instead of the class with stubs, create a plain object that maps method names to bound reducer functions:
Step 3: Update
Farmhandcomponent to use the interface directlyThe
Farmhandcomponent (insrc/components/Farmhand/Farmhand.tsx) usesuseFarmhandhook which currently interacts with theFarmhandReducersclass. Update the hook to work with theReducerMethodsinterface directly.Step 4: Remove the
FarmhandReducersclassDelete the
FarmhandReducersclass entirely, keeping only theReducerMethodsinterface and the bound object.Step 5: Run type checker
Acceptance Criteria
ReducerMethodsinterface is defined with all 50+ method signatures matching the reducers insrc/game-logic/reducers/FarmhandReducersclass is removed (no more stub methods withany[])any[]parameter lists remain in the reducer binding codenpm run check:typespasses with no errorsnpm testpasses