diff --git a/tsc/internal/compiler/fileloader.go b/tsc/internal/compiler/fileloader.go
index f8bba578a534a..c37a678d4ffec 100644
--- a/tsc/internal/compiler/fileloader.go
+++ b/tsc/internal/compiler/fileloader.go
@@ -886,6 +886,18 @@ func (p *fileLoader) resolveImportsAndModuleAugmentations(t *parseTask) {
}
mode := getModeForUsageLocation(file.FileName(), meta, entry, optionsForFile)
+ // We know moduleName resolves to an ambient module provided that moduleName:
+ // - is in the list of ambient modules locally declared in the current source file.
+ if slices.Contains(file.AmbientModuleNames, moduleName) {
+ if optionsForFile.TraceResolution.IsTrue() {
+ resolutionsTrace = append(resolutionsTrace, module.DiagAndArgs{
+ Message: diagnostics.Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1,
+ Args: []any{moduleName, file.FileName()},
+ })
+ }
+ resolutionsInFile[module.ModeAwareCacheKey{Name: moduleName, Mode: mode}] = &module.ResolvedModule{}
+ continue
+ }
var resolvedModule *module.ResolvedModule
var trace []module.DiagAndArgs
var err error
diff --git a/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.errors.txt b/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.errors.txt
new file mode 100644
index 0000000000000..1b2c6e7d3a294
--- /dev/null
+++ b/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.errors.txt
@@ -0,0 +1,25 @@
+/a.ts(2,1): error TS2304: Cannot find name 'fooGlobal'.
+
+
+==== /a.ts (1 errors) ====
+ ///
+ fooGlobal;
+ ~~~~~~~~~
+!!! error TS2304: Cannot find name 'fooGlobal'.
+
+==== /node_modules/foo/package.json (0 errors) ====
+ { "name": "foo", "version": "1.0.0", "types": "index.d.ts" }
+
+==== /node_modules/foo/index.d.ts (0 errors) ====
+ declare global {
+ var fooGlobal: string;
+ }
+ declare function foo(value: unknown): boolean;
+ export default foo;
+
+==== /declarations.d.ts (0 errors) ====
+ declare module "foo" {
+ import _foo from "foo";
+ export function isFoo(value: unknown): boolean;
+ }
+
\ No newline at end of file
diff --git a/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.js b/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.js
new file mode 100644
index 0000000000000..194020a028d0c
--- /dev/null
+++ b/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.js
@@ -0,0 +1,27 @@
+//// [tests/cases/compiler/ambientModuleImportingItselfNotResolved.ts] ////
+
+//// [package.json]
+{ "name": "foo", "version": "1.0.0", "types": "index.d.ts" }
+
+//// [index.d.ts]
+declare global {
+ var fooGlobal: string;
+}
+declare function foo(value: unknown): boolean;
+export default foo;
+
+//// [declarations.d.ts]
+declare module "foo" {
+ import _foo from "foo";
+ export function isFoo(value: unknown): boolean;
+}
+
+//// [a.ts]
+///
+fooGlobal;
+
+
+//// [a.js]
+"use strict";
+///
+fooGlobal;
diff --git a/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.symbols b/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.symbols
new file mode 100644
index 0000000000000..fab01f6eb827e
--- /dev/null
+++ b/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.symbols
@@ -0,0 +1,19 @@
+//// [tests/cases/compiler/ambientModuleImportingItselfNotResolved.ts] ////
+
+=== /a.ts ===
+
+///
+fooGlobal;
+
+=== /declarations.d.ts ===
+declare module "foo" {
+>"foo" : Symbol(_foo, Decl(declarations.d.ts, 0, 0))
+
+ import _foo from "foo";
+>_foo : Symbol(_foo, Decl(declarations.d.ts, 1, 10))
+
+ export function isFoo(value: unknown): boolean;
+>isFoo : Symbol(isFoo, Decl(declarations.d.ts, 1, 27))
+>value : Symbol(value, Decl(declarations.d.ts, 2, 26))
+}
+
diff --git a/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.trace.json b/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.trace.json
new file mode 100644
index 0000000000000..d403a0e3b4f6e
--- /dev/null
+++ b/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.trace.json
@@ -0,0 +1 @@
+Module 'foo' was resolved as locally declared ambient module in file '/declarations.d.ts'.
diff --git a/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.types b/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.types
new file mode 100644
index 0000000000000..300793c04bba9
--- /dev/null
+++ b/tsc/testdata/baselines/reference/compiler/ambientModuleImportingItselfNotResolved.types
@@ -0,0 +1,19 @@
+//// [tests/cases/compiler/ambientModuleImportingItselfNotResolved.ts] ////
+
+=== /a.ts ===
+///
+fooGlobal;
+>fooGlobal : any
+
+=== /declarations.d.ts ===
+declare module "foo" {
+>"foo" : typeof _foo
+
+ import _foo from "foo";
+>_foo : typeof _foo
+
+ export function isFoo(value: unknown): boolean;
+>isFoo : (value: unknown) => boolean
+>value : unknown
+}
+
diff --git a/tsc/testdata/baselines/reference/compiler/nodeColonModuleResolution.trace.json b/tsc/testdata/baselines/reference/compiler/nodeColonModuleResolution.trace.json
index 7484c14bb1785..4838932736fcb 100644
--- a/tsc/testdata/baselines/reference/compiler/nodeColonModuleResolution.trace.json
+++ b/tsc/testdata/baselines/reference/compiler/nodeColonModuleResolution.trace.json
@@ -1,35 +1,9 @@
-======== Resolving module 'ph' from '/a/b/node_modules/@types/node/ph.d.ts'. ========
+Module 'ph' was resolved as locally declared ambient module in file '/a/b/node_modules/@types/node/ph.d.ts'.
+======== Resolving module 'node:ph' from '/a/b/main.ts'. ========
Explicitly specified module resolution kind: 'Bundler'.
Resolving in CJS mode with conditions 'import', 'types'.
-File '/a/b/node_modules/@types/node/package.json' does not exist.
-File '/a/b/node_modules/@types/package.json' does not exist.
-File '/a/b/node_modules/package.json' does not exist.
File '/a/b/package.json' does not exist.
File '/a/package.json' does not exist.
File '/package.json' does not exist.
-Loading module 'ph' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.
-Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.
-Directory '/a/b/node_modules/@types/node/node_modules' does not exist, skipping all lookups in it.
-Directory '/a/b/node_modules/@types/node_modules' does not exist, skipping all lookups in it.
-File '/a/b/node_modules/ph.ts' does not exist.
-File '/a/b/node_modules/ph.tsx' does not exist.
-File '/a/b/node_modules/ph.d.ts' does not exist.
-File '/a/b/node_modules/@types/ph.d.ts' does not exist.
-Directory '/a/node_modules' does not exist, skipping all lookups in it.
-Directory '/node_modules' does not exist, skipping all lookups in it.
-Searching all ancestor node_modules directories for fallback extensions: JavaScript, JSON.
-Directory '/a/b/node_modules/@types/node/node_modules' does not exist, skipping all lookups in it.
-Directory '/a/b/node_modules/@types/node_modules' does not exist, skipping all lookups in it.
-File '/a/b/node_modules/ph.js' does not exist.
-File '/a/b/node_modules/ph.jsx' does not exist.
-Directory '/a/node_modules' does not exist, skipping all lookups in it.
-Directory '/node_modules' does not exist, skipping all lookups in it.
-======== Module name 'ph' was not resolved. ========
-======== Resolving module 'node:ph' from '/a/b/main.ts'. ========
-Explicitly specified module resolution kind: 'Bundler'.
-Resolving in CJS mode with conditions 'import', 'types'.
-File '/a/b/package.json' does not exist according to earlier cached lookups.
-File '/a/package.json' does not exist according to earlier cached lookups.
-File '/package.json' does not exist according to earlier cached lookups.
Skipping module 'node:ph' that looks like an absolute URI, target file types: TypeScript, JavaScript, Declaration, JSON.
======== Module name 'node:ph' was not resolved. ========
diff --git a/tsc/testdata/tests/cases/compiler/ambientModuleImportingItselfNotResolved.ts b/tsc/testdata/tests/cases/compiler/ambientModuleImportingItselfNotResolved.ts
new file mode 100644
index 0000000000000..1493925999644
--- /dev/null
+++ b/tsc/testdata/tests/cases/compiler/ambientModuleImportingItselfNotResolved.ts
@@ -0,0 +1,28 @@
+// @target: esnext
+// @module: preserve
+// @moduleResolution: bundler
+// @noImplicitReferences: true
+// @traceResolution: true
+
+// An import inside an ambient module declaration that names the same module
+// resolves to that declaration, so the real package must not be pulled in.
+
+// @filename: /node_modules/foo/package.json
+{ "name": "foo", "version": "1.0.0", "types": "index.d.ts" }
+
+// @filename: /node_modules/foo/index.d.ts
+declare global {
+ var fooGlobal: string;
+}
+declare function foo(value: unknown): boolean;
+export default foo;
+
+// @filename: /declarations.d.ts
+declare module "foo" {
+ import _foo from "foo";
+ export function isFoo(value: unknown): boolean;
+}
+
+// @filename: /a.ts
+///
+fooGlobal;