What
TypeScript bodyless declarations are extracted as functions on purpose (#2278, #2279, #2232), and that part is fine. But the call resolver then treats them as call targets. A call such as schema.check(...) links confidently to the interface's check(...): this; signature. It should link to the implementation that actually runs, or be left unresolved. A signature never runs, so these links give fan-in and PageRank to declarations with no code.
Evidence
This comes from the new TypeScript Level 2 check (tests/tools/call_graph_resolution.py typescript, branch claude/optimistic-heisenberg-bta91d) on zod (colinhacks/zod@2bf7b0630d53). About 211 of the engine's confident links have a callee the TypeScript checker knows no function for. About 205 of those are bodyless signatures:
packages/zod/src/v4/classic/schemas.ts:53 check(...checks): this;: interface ZodType (the target of many file-step links from cidrv4, uuidv4, duration, nonempty, …)
packages/zod/src/v4/core/schemas.ts:119 run(payload, ctx): util.MaybeAsync<ParsePayload>;: interface member
packages/zod/src/v3/types.ts:170 abstract _parse(input: ParseInput): ParseReturnType<Output>;
packages/zod/src/v4/core/core.ts:10 init(inst: T, def: D): asserts inst is T;
The check reports these as confident_unmapped (224 total, including caller ends).
Likely direction
The detector knows when a unit has no body. Record that on the function (or reuse an existing field), and have the resolver skip bodyless definitions when a same-named definition with a body exists. When no such definition exists, the link should drop to ambiguous, not confident. abstract methods and interface members could arguably still earn a type-hierarchy edge, but not a call edge. Once this is fixed, the check's confident_unmapped should fall sharply and judged links should rise.
What
TypeScript bodyless declarations are extracted as functions on purpose (#2278, #2279, #2232), and that part is fine. But the call resolver then treats them as call targets. A call such as
schema.check(...)links confidently to the interface'scheck(...): this;signature. It should link to the implementation that actually runs, or be left unresolved. A signature never runs, so these links give fan-in and PageRank to declarations with no code.Evidence
This comes from the new TypeScript Level 2 check (
tests/tools/call_graph_resolution.py typescript, branchclaude/optimistic-heisenberg-bta91d) on zod (colinhacks/zod@2bf7b0630d53). About 211 of the engine's confident links have a callee the TypeScript checker knows no function for. About 205 of those are bodyless signatures:packages/zod/src/v4/classic/schemas.ts:53check(...checks): this;: interfaceZodType(the target of manyfile-step links fromcidrv4,uuidv4,duration,nonempty, …)packages/zod/src/v4/core/schemas.ts:119run(payload, ctx): util.MaybeAsync<ParsePayload>;: interface memberpackages/zod/src/v3/types.ts:170abstract _parse(input: ParseInput): ParseReturnType<Output>;packages/zod/src/v4/core/core.ts:10init(inst: T, def: D): asserts inst is T;The check reports these as
confident_unmapped(224 total, including caller ends).Likely direction
The detector knows when a unit has no body. Record that on the function (or reuse an existing field), and have the resolver skip bodyless definitions when a same-named definition with a body exists. When no such definition exists, the link should drop to ambiguous, not confident.
abstractmethods and interface members could arguably still earn a type-hierarchy edge, but not acalledge. Once this is fixed, the check'sconfident_unmappedshould fall sharply and judged links should rise.