refactor: eliminate as any type casts across 18 source files
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m34s

- Fix computeDisciplineEffects() to not require GameState parameter
- Fix getUnifiedEffects() to accept proper partial state type
- Replace upgradeEffects as any with proper UnifiedEffects type
- Replace explicit : any annotations with proper types (ComputedEffects, DesignProgress, SpellDef, etc.)
- Fix activity-log.ts eventType casting
- Fix crafting-design.ts computedEffects and designProgress types
- Fix page.tsx grimoire spell rendering with proper SpellDef property names
- Fix StatsTab ManaStatsSection with proper ManaStatsEffects interface
- Remove unused imports (useDisciplineStore from page.tsx, LeftPanel.tsx)

Remaining: 1 as any in craftingStore.ts (pre-existing CraftingStore/GameState architectural mismatch)
This commit is contained in:
2026-05-20 17:22:52 +02:00
parent df316c2865
commit 742a992d59
36 changed files with 1820 additions and 1460 deletions
@@ -3,9 +3,10 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Swords } from 'lucide-react';
import { fmt, fmtDec } from '@/lib/game/stores';
import type { SpellDef } from '@/lib/game/types';
interface CombatStatsSectionProps {
activeSpellDef: any;
activeSpellDef: SpellDef | null;
pactMultiplier: number;
}
@@ -6,6 +6,7 @@ import { FlaskConical } from 'lucide-react';
import { ELEMENTS } from '@/lib/game/constants';
import { fmt, fmtDec } from '@/lib/game/stores';
import { usePrestigeStore, useManaStore } from '@/lib/game/stores';
import type { ElementState } from '@/lib/game/types';
interface ElementStatsSectionProps {
elemMax: number;
@@ -38,16 +39,16 @@ export function ElementStatsSection({ elemMax }: ElementStatsSectionProps) {
<div className="space-y-2">
<div className="flex justify-between text-sm">
<span style={{ color: 'var(--text-muted)' }}>Unlocked Elements:</span>
<span style={{ color: 'var(--color-success)' }}>{Object.values(elements || {}).filter((e: any) => e.unlocked).length} / {Object.keys(ELEMENTS).length}</span>
<span style={{ color: 'var(--color-success)' }}>{Object.values(elements || {}).filter((e: ElementState) => e.unlocked).length} / {Object.keys(ELEMENTS).length}</span>
</div>
</div>
</div>
<Separator className="bg-[var(--border-subtle)] my-3" />
<div className="text-xs" style={{ color: 'var(--text-muted)' }}>Elemental Mana Pools:</div>
<div className="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 gap-2">
{Object.entries(elements)
.filter(([, state]: [string, any]) => state.unlocked)
.map(([id, state]: [string, any]) => {
{Object.entries(elements || {})
.filter((entry): entry is [string, ElementState] => entry[1].unlocked)
.map(([id, state]) => {
const def = ELEMENTS[id];
return (
<div key={id} className="p-2 rounded transition-colors" style={{ border: `1px solid ${def?.color}30`, background: 'var(--bg-sunken)/50', textAlign: 'center' }}>
@@ -5,6 +5,7 @@ import { Separator } from '@/components/ui/separator';
import { RotateCcw } from 'lucide-react';
import { fmt } from '@/lib/game/stores';
import { useCombatStore, usePrestigeStore, useManaStore } from '@/lib/game/stores';
import type { SpellState } from '@/lib/game/types';
export function LoopStatsSection() {
const spells = useCombatStore((s) => s.spells);
@@ -15,7 +16,7 @@ export function LoopStatsSection() {
const loopCount = usePrestigeStore((s) => s.loopCount);
const memorySlots = usePrestigeStore((s) => s.memorySlots);
const spellsLearned = Object.values(spells || {}).filter((s: any) => s.learned).length;
const spellsLearned = Object.values(spells || {}).filter((s: SpellState) => s.learned).length;
return (
<Card className="bg-[var(--bg-panel)] border-[var(--border-subtle)]">
@@ -3,6 +3,20 @@
import { fmt, fmtDec } from '@/lib/game/stores';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Droplet } from 'lucide-react';
import type { ComputedEffects } from '@/lib/game/effects/upgrade-effects.types';
interface ManaStatsEffects extends ComputedEffects {
incursionStrength: number;
rawMana: number;
hasSteadyStream: boolean;
hasManaTorrent: boolean;
hasDesperateWells: boolean;
manaCascadeBonus: number;
manaWaterfallBonus: number;
hasFlowSurge: boolean;
hasManaOverflow: boolean;
hasEternalFlow: boolean;
}
interface ManaStatsSectionProps {
maxMana: number;
@@ -10,7 +24,7 @@ interface ManaStatsSectionProps {
effectiveRegen: number;
clickMana: number;
meditationMultiplier: number;
upgradeEffects: any;
upgradeEffects: ManaStatsEffects;
elemMax: number;
}