Skip to content

fix 1.1 Unsafe as casts in reducer.ts (~21 instances) #2

Description

@joshmarinacci

File: src/store/reducer.ts

Problem:
The reducer uses as casts pervasively to bypass the TypeScript type system rather than narrowing types properly. This makes refactoring dangerous — TypeScript will not catch mismatches.

Key examples:

// Line 666 — double cast is always a red flag
rest as unknown as Shape

// Lines 521–526 — no type guard before casting
const img = shape as ImageShape
img.assetId = action.assetId // crashes silently if shape is not ImageShape

// Line 300 — patch can add or remove required fields
{ ...shape, ...action.patch } as Shape
Why it matters:
A as SomeType cast tells TypeScript "trust me, this is correct" but gives you nothing at runtime. If a shape that is not an ImageShape ends up in a code path that casts it to one, the app silently reads undefined fields instead of throwing — making bugs very hard to trace.

Fix:
Replace as casts with discriminated union narrowing using the type field already present on shapes:

// Before
const img = shape as ImageShape

// After
if (shape.type !== 'image') return state // or throw in dev
const img = shape // TypeScript now knows this is ImageShape
For action.patch, define typed patch interfaces per action instead of spreading into a generic Shape.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions