Skip to content

Commit d84f6b5

Browse files
committed
refactor: widen outputResult signature, remove redundant casts at call sites
outputResult took data: Record<string, any>, whose any-typed index signature already made TypeScript skip the "index signature is missing" check for plain interfaces -- so callers never actually needed the defensive `as unknown as Record<string, unknown>` cast; they just carried it forward as noise. Widen the parameter to `object` (outputResult only serializes/ formats data and never returns or re-exposes its shape, so a generic isn't needed) and move the one necessary cast to Record<string, unknown> inside outputResult itself, where it's actually justified by printNdjson/printCsv/ printAutoTable needing key access for NDJSON field plucking and CSV/table flattening. Removes the cast from all 22 current call sites across audit.ts, triage.ts, owners.ts, and queries-cli/{impact,path,exports, inspect,overview}.ts. docs check acknowledged: internal type-signature cleanup only, no new features/languages/architecture/CLI surface -- README.md, CLAUDE.md, and ROADMAP.md do not need updates. Fixes #1803 Impact: 23 functions changed, 79 affected
1 parent a79a8a1 commit d84f6b5

9 files changed

Lines changed: 31 additions & 34 deletions

File tree

src/presentation/audit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export function audit(
9494
): void {
9595
const data: AuditResult = auditData(target, customDbPath, opts);
9696

97-
if (outputResult(data as unknown as Record<string, unknown>, null, opts)) return;
97+
if (outputResult(data, null, opts)) return;
9898

9999
if (data.functions.length === 0) {
100100
console.log(`No ${data.kind === 'file' ? 'file' : 'function/symbol'} matching "${target}"`);

src/presentation/owners.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ interface OwnersResult {
4343

4444
export function owners(customDbPath: string | undefined, opts: OwnersOpts = {}): void {
4545
const data = ownersData(customDbPath, opts as any) as OwnersResult;
46-
if (outputResult(data as unknown as Record<string, unknown>, null, opts)) return;
46+
if (outputResult(data, null, opts)) return;
4747

4848
if (!data.codeownersFile) {
4949
console.log('No CODEOWNERS file found.');

src/presentation/queries-cli/exports.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ function printReexportedSection(data: ExportsDataResult, opts: ExportsOpts): voi
123123

124124
export function fileExports(file: string, customDbPath: string, opts: ExportsOpts = {}): void {
125125
const data = exportsData(file, customDbPath, opts) as ExportsDataResult;
126-
if (outputResult(data as unknown as Record<string, unknown>, 'results', opts)) return;
126+
if (outputResult(data, 'results', opts)) return;
127127

128128
const hasReexported = data.reexportedSymbols && data.reexportedSymbols.length > 0;
129129

src/presentation/queries-cli/impact.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ interface OutputOpts {
126126

127127
export function fileDeps(file: string, customDbPath: string, opts: OutputOpts = {}): void {
128128
const data = fileDepsData(file, customDbPath, opts) as unknown as FileDepsData;
129-
if (outputResult(data as unknown as Record<string, unknown>, 'results', opts)) return;
129+
if (outputResult(data, 'results', opts)) return;
130130

131131
if (data.results.length === 0) {
132132
console.log(`No file matching "${file}" in graph`);
@@ -181,7 +181,7 @@ function printFnDepsTransitive(transitiveCallers: Record<string, SymbolRef[]>):
181181

182182
export function fnDeps(name: string, customDbPath: string, opts: OutputOpts = {}): void {
183183
const data = fnDepsData(name, customDbPath, opts) as unknown as FnDepsData;
184-
if (outputResult(data as unknown as Record<string, unknown>, 'results', opts)) return;
184+
if (outputResult(data, 'results', opts)) return;
185185

186186
if (data.results.length === 0) {
187187
console.log(`No function/method/class matching "${name}"`);
@@ -202,7 +202,7 @@ export function fnDeps(name: string, customDbPath: string, opts: OutputOpts = {}
202202

203203
export function impactAnalysis(file: string, customDbPath: string, opts: OutputOpts = {}): void {
204204
const data = impactAnalysisData(file, customDbPath, opts) as unknown as ImpactData;
205-
if (outputResult(data as unknown as Record<string, unknown>, 'sources', opts)) return;
205+
if (outputResult(data, 'sources', opts)) return;
206206

207207
if (data.sources.length === 0) {
208208
console.log(`No file matching "${file}" in graph`);
@@ -231,7 +231,7 @@ export function impactAnalysis(file: string, customDbPath: string, opts: OutputO
231231

232232
export function fnImpact(name: string, customDbPath: string, opts: OutputOpts = {}): void {
233233
const data = fnImpactData(name, customDbPath, opts) as unknown as FnImpactData;
234-
if (outputResult(data as unknown as Record<string, unknown>, 'results', opts)) return;
234+
if (outputResult(data, 'results', opts)) return;
235235

236236
if (data.results.length === 0) {
237237
console.log(`No function/method/class matching "${name}"`);
@@ -302,7 +302,7 @@ export function diffImpact(customDbPath: string, opts: OutputOpts = {}): void {
302302
}
303303
const data = diffImpactData(customDbPath, opts) as unknown as DiffImpactData;
304304
if (opts.format === 'json') opts = { ...opts, json: true };
305-
if (outputResult(data as unknown as Record<string, unknown>, 'affectedFunctions', opts)) return;
305+
if (outputResult(data, 'affectedFunctions', opts)) return;
306306

307307
if (data.error) {
308308
console.log(data.error);

src/presentation/queries-cli/inspect.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ function renderWhereFileResults(results: WhereFileResult[]): void {
222222

223223
export function where(target: string, customDbPath: string, opts: OutputOpts = {}): void {
224224
const data = whereData(target, customDbPath, opts as Record<string, unknown>) as WhereData;
225-
if (outputResult(data as unknown as Record<string, unknown>, 'results', opts)) return;
225+
if (outputResult(data, 'results', opts)) return;
226226

227227
if (data.results.length === 0) {
228228
console.log(
@@ -247,7 +247,7 @@ export function queryName(name: string, customDbPath: string, opts: OutputOpts =
247247
limit: opts.limit,
248248
offset: opts.offset,
249249
}) as QueryNameData;
250-
if (outputResult(data as unknown as Record<string, unknown>, 'results', opts)) return;
250+
if (outputResult(data, 'results', opts)) return;
251251

252252
if (data.results.length === 0) {
253253
console.log(`No results for "${name}"`);
@@ -275,7 +275,7 @@ export function queryName(name: string, customDbPath: string, opts: OutputOpts =
275275

276276
export function context(name: string, customDbPath: string, opts: OutputOpts = {}): void {
277277
const data = contextData(name, customDbPath, opts as Record<string, unknown>) as ContextData;
278-
if (outputResult(data as unknown as Record<string, unknown>, 'results', opts)) return;
278+
if (outputResult(data, 'results', opts)) return;
279279

280280
if (data.results.length === 0) {
281281
console.log(`No function/method/class matching "${name}"`);
@@ -289,7 +289,7 @@ export function context(name: string, customDbPath: string, opts: OutputOpts = {
289289

290290
export function children(name: string, customDbPath: string, opts: OutputOpts = {}): void {
291291
const data = childrenData(name, customDbPath, opts as Record<string, unknown>) as ChildrenData;
292-
if (outputResult(data as unknown as Record<string, unknown>, 'results', opts)) return;
292+
if (outputResult(data, 'results', opts)) return;
293293

294294
if (data.results.length === 0) {
295295
console.log(`No symbol matching "${name}"`);
@@ -505,7 +505,7 @@ function renderFunctionExplain(r: FunctionExplainResult, indent = ''): void {
505505

506506
export function explain(target: string, customDbPath: string, opts: OutputOpts = {}): void {
507507
const data = explainData(target, customDbPath, opts as Record<string, unknown>) as ExplainData;
508-
if (outputResult(data as unknown as Record<string, unknown>, 'results', opts)) return;
508+
if (outputResult(data, 'results', opts)) return;
509509

510510
if (data.results.length === 0) {
511511
console.log(`No ${data.kind === 'file' ? 'file' : 'function/symbol'} matching "${target}"`);
@@ -529,7 +529,7 @@ export function implementations(name: string, customDbPath: string, opts: Output
529529
customDbPath,
530530
opts as Record<string, unknown>,
531531
) as ImplementationsData;
532-
if (outputResult(data as unknown as Record<string, unknown>, 'results', opts)) return;
532+
if (outputResult(data, 'results', opts)) return;
533533

534534
if (data.results.length === 0) {
535535
console.log(`No symbol matching "${name}"`);
@@ -556,7 +556,7 @@ export function interfaces(name: string, customDbPath: string, opts: OutputOpts
556556
customDbPath,
557557
opts as Record<string, unknown>,
558558
) as InterfacesData;
559-
if (outputResult(data as unknown as Record<string, unknown>, 'results', opts)) return;
559+
if (outputResult(data, 'results', opts)) return;
560560

561561
if (data.results.length === 0) {
562562
console.log(`No symbol matching "${name}"`);

src/presentation/queries-cli/overview.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ export async function stats(customDbPath: string, opts: OutputOpts = {}): Promis
262262
debug(`stats: community detection failed (optional): ${toErrorMessage(e)}`);
263263
}
264264

265-
if (outputResult(data as unknown as Record<string, unknown>, null, opts)) return;
265+
if (outputResult(data, null, opts)) return;
266266

267267
console.log('\n# Codegraph Stats\n');
268268
printNodes(data);
@@ -280,7 +280,7 @@ export async function stats(customDbPath: string, opts: OutputOpts = {}): Promis
280280

281281
export function moduleMap(customDbPath: string, limit = 20, opts: OutputOpts = {}): void {
282282
const data = moduleMapData(customDbPath, limit, { noTests: opts.noTests }) as ModuleMapData;
283-
if (outputResult(data as unknown as Record<string, unknown>, 'topNodes', opts)) return;
283+
if (outputResult(data, 'topNodes', opts)) return;
284284

285285
console.log(`\nModule map (top ${limit} most-connected nodes):\n`);
286286
const dirs = new Map<string, TopNode[]>();
@@ -326,11 +326,7 @@ function printRoleGroup(role: string, symbols: RoleSymbol[]): void {
326326
export function dynamicCalls(customDbPath: string, opts: OutputOpts = {}): void {
327327
const rows = dynamicCallsData(customDbPath);
328328
if (opts.json || opts.ndjson) {
329-
outputResult(
330-
{ dynamic_calls: rows } as unknown as Record<string, unknown>,
331-
'dynamic_calls',
332-
opts,
333-
);
329+
outputResult({ dynamic_calls: rows }, 'dynamic_calls', opts);
334330
return;
335331
}
336332
if (rows.length === 0) {
@@ -353,7 +349,7 @@ export function dynamicCalls(customDbPath: string, opts: OutputOpts = {}): void
353349

354350
export function roles(customDbPath: string, opts: OutputOpts = {}): void {
355351
const data = rolesData(customDbPath, opts) as RolesData;
356-
if (outputResult(data as unknown as Record<string, unknown>, 'symbols', opts)) return;
352+
if (outputResult(data, 'symbols', opts)) return;
357353

358354
if (data.count === 0) {
359355
console.log('No classified symbols found. Run "codegraph build" first.');

src/presentation/queries-cli/path.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export function symbolPath(
8686
}
8787

8888
const data = pathData(from, to, customDbPath, opts) as PathDataResult;
89-
if (outputResult(data as unknown as Record<string, unknown>, null, opts)) return;
89+
if (outputResult(data, null, opts)) return;
9090

9191
if (data.error) {
9292
console.log(data.error);
@@ -160,7 +160,7 @@ function printFilePathSteps(data: FilePathDataResult): void {
160160

161161
function filePath(from: string, to: string, customDbPath: string, opts: PathOpts = {}): void {
162162
const data = filePathData(from, to, customDbPath, opts) as FilePathDataResult;
163-
if (outputResult(data as unknown as Record<string, unknown>, null, opts)) return;
163+
if (outputResult(data, null, opts)) return;
164164

165165
if (data.error) {
166166
console.log(data.error);

src/presentation/result-formatter.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,17 +132,18 @@ export interface OutputOpts {
132132
display?: DisplayOpts;
133133
}
134134

135-
export function outputResult(
136-
data: Record<string, any>,
137-
field: string | null,
138-
opts: OutputOpts,
139-
): boolean {
135+
export function outputResult(data: object, field: string | null, opts: OutputOpts): boolean {
136+
// The formatting helpers below need key/index access (NDJSON field pluck, CSV/table
137+
// flattening). Callers only ever hand off a concrete result shape for serialization,
138+
// so the cast lives here once instead of as a defensive `as unknown as Record<...>`
139+
// at every call site.
140+
const record = data as Record<string, unknown>;
140141
if (opts.ndjson) {
141142
if (field === null) {
142143
// No field key — emit the whole object as a single NDJSON line
143144
console.log(JSON.stringify(data));
144145
} else {
145-
printNdjson(data, field);
146+
printNdjson(record, field);
146147
}
147148
return true;
148149
}
@@ -151,11 +152,11 @@ export function outputResult(
151152
return true;
152153
}
153154
if (opts.csv) {
154-
return printCsv(data, field) !== false;
155+
return printCsv(record, field) !== false;
155156
}
156157
if (opts.table) {
157158
const displayOpts = opts.display ?? (loadConfig() as { display: DisplayOpts }).display;
158-
return printAutoTable(data, field, displayOpts) !== false;
159+
return printAutoTable(record, field, displayOpts) !== false;
159160
}
160161
return false;
161162
}

src/presentation/triage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export function triage(customDbPath: string | undefined, opts: TriageOpts = {}):
4242
summary: TriageSummary;
4343
};
4444

45-
if (outputResult(data as unknown as Record<string, unknown>, 'items', opts)) return;
45+
if (outputResult(data, 'items', opts)) return;
4646

4747
if (data.items.length === 0) {
4848
if (data.summary.total === 0) {

0 commit comments

Comments
 (0)