Skip to content

Commit 46e8306

Browse files
authored
Skip ambient modules in globalThis (#48938)
* Skip ambient modules in globalThis Previously, globalThis mistakenly included ambient modules, even though these are not values: ```ts declare module "ambientModule" { export type typ = 1 export var val: typ } type Oops = (typeof globalThis)[\"ambientModule\"] ``` This PR adds ambient modules to the kinds of things that are skipped when constructing `globalThis`' properties, along with block-scoped variables. * Skip only modules with every declaration ambient The modules are required to have at least one declaration so that our treatment of `globalThis` stays the same, and `globalThis.globalThis.globalThis` remains legal.
1 parent 7d60dc1 commit 46e8306

File tree

6 files changed

+128
-1
lines changed

6 files changed

+128
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11504,7 +11504,7 @@ namespace ts {
1150411504
if (symbol === globalThisSymbol) {
1150511505
const varsOnly = new Map<string, Symbol>() as SymbolTable;
1150611506
members.forEach(p => {
11507-
if (!(p.flags & SymbolFlags.BlockScoped)) {
11507+
if (!(p.flags & SymbolFlags.BlockScoped) && !(p.flags & SymbolFlags.ValueModule && p.declarations?.length && every(p.declarations, isAmbientModule))) {
1150811508
varsOnly.set(p.escapedName, p);
1150911509
}
1151011510
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
tests/cases/conformance/es2019/globalThisAmbientModules.ts(8,39): error TS2339: Property '"ambientModule"' does not exist on type 'typeof globalThis'.
2+
tests/cases/conformance/es2019/globalThisAmbientModules.ts(11,33): error TS2339: Property '"ambientModule"' does not exist on type 'typeof globalThis'.
3+
4+
5+
==== tests/cases/conformance/es2019/globalThisAmbientModules.ts (2 errors) ====
6+
declare module "ambientModule" {
7+
export type typ = 1
8+
export var val: typ
9+
}
10+
namespace valueModule { export var val = 1 }
11+
namespace namespaceModule { export type typ = 1 }
12+
// should error
13+
type GlobalBad1 = (typeof globalThis)["\"ambientModule\""]
14+
~~~~~~~~~~~~~~~~~~~
15+
!!! error TS2339: Property '"ambientModule"' does not exist on type 'typeof globalThis'.
16+
type GlobalOk1 = (typeof globalThis)["valueModule"]
17+
type GlobalOk2 = globalThis.namespaceModule.typ
18+
const bad1: (typeof globalThis)["\"ambientModule\""] = 'ambientModule'
19+
~~~~~~~~~~~~~~~~~~~
20+
!!! error TS2339: Property '"ambientModule"' does not exist on type 'typeof globalThis'.
21+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//// [globalThisAmbientModules.ts]
2+
declare module "ambientModule" {
3+
export type typ = 1
4+
export var val: typ
5+
}
6+
namespace valueModule { export var val = 1 }
7+
namespace namespaceModule { export type typ = 1 }
8+
// should error
9+
type GlobalBad1 = (typeof globalThis)["\"ambientModule\""]
10+
type GlobalOk1 = (typeof globalThis)["valueModule"]
11+
type GlobalOk2 = globalThis.namespaceModule.typ
12+
const bad1: (typeof globalThis)["\"ambientModule\""] = 'ambientModule'
13+
14+
15+
//// [globalThisAmbientModules.js]
16+
var valueModule;
17+
(function (valueModule) {
18+
valueModule.val = 1;
19+
})(valueModule || (valueModule = {}));
20+
var bad1 = 'ambientModule';
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
=== tests/cases/conformance/es2019/globalThisAmbientModules.ts ===
2+
declare module "ambientModule" {
3+
>"ambientModule" : Symbol("ambientModule", Decl(globalThisAmbientModules.ts, 0, 0))
4+
5+
export type typ = 1
6+
>typ : Symbol(typ, Decl(globalThisAmbientModules.ts, 0, 32))
7+
8+
export var val: typ
9+
>val : Symbol(val, Decl(globalThisAmbientModules.ts, 2, 14))
10+
>typ : Symbol(typ, Decl(globalThisAmbientModules.ts, 0, 32))
11+
}
12+
namespace valueModule { export var val = 1 }
13+
>valueModule : Symbol(valueModule, Decl(globalThisAmbientModules.ts, 3, 1))
14+
>val : Symbol(val, Decl(globalThisAmbientModules.ts, 4, 34))
15+
16+
namespace namespaceModule { export type typ = 1 }
17+
>namespaceModule : Symbol(namespaceModule, Decl(globalThisAmbientModules.ts, 4, 44))
18+
>typ : Symbol(typ, Decl(globalThisAmbientModules.ts, 5, 27))
19+
20+
// should error
21+
type GlobalBad1 = (typeof globalThis)["\"ambientModule\""]
22+
>GlobalBad1 : Symbol(GlobalBad1, Decl(globalThisAmbientModules.ts, 5, 49))
23+
>globalThis : Symbol(globalThis)
24+
25+
type GlobalOk1 = (typeof globalThis)["valueModule"]
26+
>GlobalOk1 : Symbol(GlobalOk1, Decl(globalThisAmbientModules.ts, 7, 58))
27+
>globalThis : Symbol(globalThis)
28+
29+
type GlobalOk2 = globalThis.namespaceModule.typ
30+
>GlobalOk2 : Symbol(GlobalOk2, Decl(globalThisAmbientModules.ts, 8, 51))
31+
>globalThis : Symbol(globalThis)
32+
>namespaceModule : Symbol(namespaceModule, Decl(globalThisAmbientModules.ts, 4, 44))
33+
>typ : Symbol(namespaceModule.typ, Decl(globalThisAmbientModules.ts, 5, 27))
34+
35+
const bad1: (typeof globalThis)["\"ambientModule\""] = 'ambientModule'
36+
>bad1 : Symbol(bad1, Decl(globalThisAmbientModules.ts, 10, 5))
37+
>globalThis : Symbol(globalThis)
38+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
=== tests/cases/conformance/es2019/globalThisAmbientModules.ts ===
2+
declare module "ambientModule" {
3+
>"ambientModule" : typeof import("ambientModule")
4+
5+
export type typ = 1
6+
>typ : 1
7+
8+
export var val: typ
9+
>val : 1
10+
}
11+
namespace valueModule { export var val = 1 }
12+
>valueModule : typeof valueModule
13+
>val : number
14+
>1 : 1
15+
16+
namespace namespaceModule { export type typ = 1 }
17+
>typ : 1
18+
19+
// should error
20+
type GlobalBad1 = (typeof globalThis)["\"ambientModule\""]
21+
>GlobalBad1 : any
22+
>globalThis : typeof globalThis
23+
24+
type GlobalOk1 = (typeof globalThis)["valueModule"]
25+
>GlobalOk1 : typeof valueModule
26+
>globalThis : typeof globalThis
27+
28+
type GlobalOk2 = globalThis.namespaceModule.typ
29+
>GlobalOk2 : 1
30+
>globalThis : any
31+
>namespaceModule : any
32+
33+
const bad1: (typeof globalThis)["\"ambientModule\""] = 'ambientModule'
34+
>bad1 : any
35+
>globalThis : typeof globalThis
36+
>'ambientModule' : "ambientModule"
37+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
declare module "ambientModule" {
2+
export type typ = 1
3+
export var val: typ
4+
}
5+
namespace valueModule { export var val = 1 }
6+
namespace namespaceModule { export type typ = 1 }
7+
// should error
8+
type GlobalBad1 = (typeof globalThis)["\"ambientModule\""]
9+
type GlobalOk1 = (typeof globalThis)["valueModule"]
10+
type GlobalOk2 = globalThis.namespaceModule.typ
11+
const bad1: (typeof globalThis)["\"ambientModule\""] = 'ambientModule'

0 commit comments

Comments
 (0)