From 7955a534e2e06bbf6ef1dd183033bf797734689f Mon Sep 17 00:00:00 2001 From: Gergo Magyar Date: Thu, 18 Jun 2026 16:06:28 +0000 Subject: [PATCH] refactor(impact): narrow PdgImpactResult instead of `as any` for slice fields The dispatch read reachableBlocks/seedBlocks and the composer read pdgEvidence via `(pdgResult as any)`. Replace both with a discriminated-union narrow: the slice fields live only on the success/empty results, so narrowing with the same `'error' in / 'pdgLayer' in` guard the composer already uses yields the typed string[] / PdgImpactEvidenceSummary without a cast. No `as any` remain on pdgResult; behaviour is unchanged. Addresses PR #2227 tri-review finding (maintainability) and the strict-typing requirement. Co-Authored-By: Claude Opus 4.8 (1M context) --- gitnexus/src/mcp/local/local-backend.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/gitnexus/src/mcp/local/local-backend.ts b/gitnexus/src/mcp/local/local-backend.ts index a165aff2e..8c6ace8d5 100644 --- a/gitnexus/src/mcp/local/local-backend.ts +++ b/gitnexus/src/mcp/local/local-backend.ts @@ -4798,8 +4798,13 @@ export class LocalBackend { // yet `reachableBlocks` excludes the seed by the seed-minus-reachable // convention. Upstream seeds carry no discriminating slice, so the bridge // falls back to preserving callgraph reach. - const reachableBlocks = ((pdgResult as any).reachableBlocks ?? []) as string[]; - const seedBlocks = ((pdgResult as any).seedBlocks ?? []) as string[]; + // `_runImpactPDG` returns the PdgImpactResult union; only the success/empty + // slice results carry reachableBlocks/seedBlocks (degraded and error results + // do not). Narrow via the same discriminant the composer uses, then read the + // typed string[] slices — no `as any`. + const sliceResult = 'error' in pdgResult || 'pdgLayer' in pdgResult ? null : pdgResult; + const reachableBlocks: string[] = sliceResult?.reachableBlocks ?? []; + const seedBlocks: string[] = sliceResult?.seedBlocks ?? []; const sliceBlocks = [...seedBlocks, ...reachableBlocks]; const sliceCalleeNames = direction === 'downstream' && sliceBlocks.length > 0 @@ -5042,7 +5047,10 @@ export class LocalBackend { : {}), ...(errorMessage ? { interproceduralError: errorMessage } : {}), pdgEvidence: { - ...((pdgResult as any).pdgEvidence ?? {}), + // pdgResult is narrowed to the success/empty slice result by the + // `'error' in / 'pdgLayer' in` guard at the top of this method, so + // `pdgEvidence` is typed (optional) — no `as any`. + ...(pdgResult.pdgEvidence ?? {}), ...(interproceduralEvidence ? { interprocedural: interproceduralEvidence } : {}), interproceduralEvidenceCounts, },