Skip to content

Autocomplete incorrectly suggests transitive files from monorepo package #2581

@ericnorris

Description

@ericnorris

Extension Version

0.20260124.1

VS Code Version

1.108.2

Operating system Version

macOS 15.7

Steps to reproduce

I've written a failing fourslash test to demonstrate the issue:

package fourslash_test

import (
	"testing"

	"github.com/microsoft/typescript-go/internal/fourslash"
	. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
	"github.com/microsoft/typescript-go/internal/ls"
	"github.com/microsoft/typescript-go/internal/lsp/lsproto"
	"github.com/microsoft/typescript-go/internal/testutil"
)

const TestAutoImportTransitiveLeakScenario = `
// @Filename: /home/src/workspaces/project/tsconfig.base.json
{
  "compilerOptions": {
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "composite": true
  }
}

// @Filename: /home/src/workspaces/project/packages/foo/package.json
{
  "name": "@packages/foo",
  "type": "module",
  "exports": {
    ".": {
	  "types": "./src/index.ts",
	  "default": "./dist/index.js"
	}
  },
  "imports": {
    "#*": {
	  "types": "./src/*.ts",
      "default": "./dist/*.js"
    }
  }
}

// @Filename: /home/src/workspaces/project/packages/foo/tsconfig.json
{ "extends": "../../tsconfig.base.json" }

// @Filename: /home/src/workspaces/project/packages/foo/src/internal/index.ts
export function fooInternal() {
  console.log("foo");
}

// @Filename: /home/src/workspaces/project/packages/foo/src/index.ts
import { fooInternal } from "#internal/index"
export function foo() {
  fooInternal();
}

// @Filename: /home/src/workspaces/project/packages/bar/package.json
{
  "name": "@packages/bar",
  "type": "module",
  "exports": {
    ".": {
	  "types": "./src/index.ts",
	  "default": "./dist/index.js"
	}
  },
  "imports": {
    "#*": {
	  "types": "./src/*.ts",
      "default": "./dist/*.js"
    }
  },
  "dependencies": {
    "@packages/foo": "*"
  }
}

// @Filename: /home/src/workspaces/project/packages/bar/tsconfig.json
{ "extends": "../../tsconfig.base.json" }

// @Filename: /home/src/workspaces/project/packages/bar/src/index.ts
import { foo } from "@packages/foo"

fo/*fooCompletion*/

// @Filename: /home/src/workspaces/project/package.json
{ "workspaces": ["packages/*"], "type": "module" }

// @link: /home/src/workspaces/project/packages/bar -> /home/src/workspaces/project/node_modules/@packages/bar
// @link: /home/src/workspaces/project/packages/foo -> /home/src/workspaces/project/node_modules/@packages/foo
`

func TestAutoImportTransitiveLeak(t *testing.T) {
	t.Parallel()

	defer testutil.RecoverAndFail(t, "Panic on fourslash test")

	f, done := fourslash.NewFourslash(t, nil /*capabilities*/, TestAutoImportTransitiveLeakScenario)

	defer done()

	f.VerifyCompletions(t, "fooCompletion", &fourslash.CompletionsExpectedList{
		IsIncomplete: false,
		ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
			CommitCharacters: &DefaultCommitCharacters,
			EditRange:        Ignored,
		},
		Items: &fourslash.CompletionsExpectedItems{
			Includes: []fourslash.CompletionsExpectedItem{
				&lsproto.CompletionItem{
					Label:               "foo",
					AdditionalTextEdits: fourslash.AnyTextEdits,
					SortText: PtrTo(string(ls.SortTextLocationPriority)),
				},
			},
			Excludes: []string{"fooInternal"},
		},
	})
}

I placed it at internal/fourslash/tests/autoImportTransitiveLeak_test.go.

Issue

Similar to microsoft/TypeScript#63033, but I've reproduced it here. I don't believe that it should suggest fooInternal as an autocomplete, as it's not actually exported. What does happen, however, is that it suggests fooInternal, and accepting it produces the following code with a red squiggly line on the second import:

import { foo } from "@packages/foo";
import { fooInternal } from "@packages/foo/src/internal/index.js";

fooInternal

The diagnostic then says Cannot find module '@packages/foo/src/internal/index.js' or its corresponding type declarations.

Additional information about the issue

This was very difficult for me to reproduce, but I believe I've identified two variables that prevent the bug from surfacing:

  • Add a version field to the packages/foo/package.json, or
  • Add "preserveSymlinks": true to tsconfig.base.json

Metadata

Metadata

Labels

Domain: EditorRelated to the LSP server, editor experience

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions