Skip to content

Call resolver (TS/JS): a bare call to a named import resolves to a same-named member of a namespace import (import { clone } vs import * as schemas) #3758

Description

@squid-protocol

What

// packages/zod/src/v4/classic/in-out.ts (colinhacks/zod@2bf7b0630d53)
import { clone, mergeDefs } from "../core/util.js";
import * as schemas from "./schemas.js";

function withChecks(side, checks) {
  ...
  return clone(side, mergeDefs(def, { ... }), { parent: true });
}

The engine links the bare clone(...) (step import) to clone at v4/classic/schemas.ts:202, a method inside an object literal in the namespace-imported module. The call is to v4/core/util.ts:645 clone, which is named in the import. packages/zod/src/v4/mini/in-out.ts has the same shape (it resolves to mini/schemas.ts:90).

The TypeScript checker flags both as wrong in the new Level 2 TypeScript check (tests/tools/call_graph_resolution.py typescript, branch claude/optimistic-heisenberg-bta91d).

Likely direction

A bare call can only reach a binding in scope. A name listed in import { … } is exactly that binding. A namespace import (import * as ns) reaches its members only as ns.clone(...). So for a bare call, the import step should prefer a file whose import statement names the callee. A namespace import's members should count only for a call qualified with that namespace's alias.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugUnintended behavior or logic failure in the enginecore-engineModifications to the central physics and parsing engine

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions