Skip to content

Commit 2103ed6

Browse files
authored
Merge pull request #28782 from weswigham/global-merge-no-crash
Fix crash on umd and module merge, allow umds to be accessed when merged with a non-UMD symbol
2 parents 03a98a2 + d92771d commit 2103ed6

6 files changed

+126
-19
lines changed

src/compiler/checker.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,7 +1569,8 @@ namespace ts {
15691569

15701570
// If we're in an external module, we can't reference value symbols created from UMD export declarations
15711571
if (result && isInExternalModule && (meaning & SymbolFlags.Value) === SymbolFlags.Value && !(originalLocation!.flags & NodeFlags.JSDoc)) {
1572-
if (some(result.declarations, d => isNamespaceExportDeclaration(d) || isSourceFile(d) && !!d.symbol.globalExports)) {
1572+
const merged = getMergedSymbol(result);
1573+
if (length(merged.declarations) && every(merged.declarations, d => isNamespaceExportDeclaration(d) || isSourceFile(d) && !!d.symbol.globalExports)) {
15731574
error(errorLocation!, Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, unescapeLeadingUnderscores(name)); // TODO: GH#18217
15741575
}
15751576
}
@@ -5322,12 +5323,11 @@ namespace ts {
53225323
return anyType;
53235324
}
53245325
// Handle export default expressions
5325-
if (isSourceFile(declaration)) {
5326-
const jsonSourceFile = cast(declaration, isJsonSourceFile);
5327-
if (!jsonSourceFile.statements.length) {
5326+
if (isSourceFile(declaration) && isJsonSourceFile(declaration)) {
5327+
if (!declaration.statements.length) {
53285328
return emptyObjectType;
53295329
}
5330-
const type = getWidenedLiteralType(checkExpression(jsonSourceFile.statements[0].expression));
5330+
const type = getWidenedLiteralType(checkExpression(declaration.statements[0].expression));
53315331
if (type.flags & TypeFlags.Object) {
53325332
return getRegularTypeOfObjectLiteral(type);
53335333
}
@@ -5352,7 +5352,8 @@ namespace ts {
53525352
|| isClassDeclaration(declaration)
53535353
|| isFunctionDeclaration(declaration)
53545354
|| (isMethodDeclaration(declaration) && !isObjectLiteralMethod(declaration))
5355-
|| isMethodSignature(declaration)) {
5355+
|| isMethodSignature(declaration)
5356+
|| isSourceFile(declaration)) {
53565357
// Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty`
53575358
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) {
53585359
return getTypeOfFuncClassEnumModule(symbol);

tests/baselines/reference/exportAsNamespace_augment.errors.txt

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
/a.d.ts(3,14): error TS2451: Cannot redeclare block-scoped variable 'conflict'.
22
/b.ts(6,22): error TS2451: Cannot redeclare block-scoped variable 'conflict'.
33
/b.ts(12,18): error TS2451: Cannot redeclare block-scoped variable 'conflict'.
4-
/b.ts(15,1): error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
5-
/b.ts(15,7): error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
6-
/b.ts(15,13): error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
7-
/b.ts(15,19): error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
84

95

106
==== /a.d.ts (1 errors) ====
@@ -16,7 +12,7 @@
1612
!!! related TS6203 /b.ts:6:22: 'conflict' was also declared here.
1713
!!! related TS6204 /b.ts:12:18: and here.
1814

19-
==== /b.ts (6 errors) ====
15+
==== /b.ts (2 errors) ====
2016
import * as a2 from "./a";
2117

2218
declare global {
@@ -38,13 +34,5 @@
3834
}
3935

4036
a.x + a.y + a.z + a.conflict;
41-
~
42-
!!! error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
43-
~
44-
!!! error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
45-
~
46-
!!! error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
47-
~
48-
!!! error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
4937
a2.x + a2.y + a2.z + a2.conflict;
5038

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//// [tests/cases/compiler/umdGlobalAugmentationNoCrash.ts] ////
2+
3+
//// [global.d.ts]
4+
declare global {
5+
const React: typeof import("./module");
6+
}
7+
export {};
8+
9+
//// [module.d.ts]
10+
export as namespace React;
11+
export function foo(): string;
12+
13+
//// [some_module.ts]
14+
export {}
15+
React.foo;
16+
17+
//// [emits.ts]
18+
console.log("hello");
19+
React.foo;
20+
21+
22+
//// [some_module.js]
23+
React.foo;
24+
//// [emits.js]
25+
"use strict";
26+
console.log("hello");
27+
React.foo;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
=== tests/cases/compiler/global.d.ts ===
2+
declare global {
3+
>global : Symbol(global, Decl(global.d.ts, 0, 0))
4+
5+
const React: typeof import("./module");
6+
>React : Symbol("tests/cases/compiler/module", Decl(module.d.ts, 0, 0), Decl(global.d.ts, 1, 9))
7+
}
8+
export {};
9+
10+
=== tests/cases/compiler/module.d.ts ===
11+
export as namespace React;
12+
>React : Symbol(React, Decl(module.d.ts, 0, 0))
13+
14+
export function foo(): string;
15+
>foo : Symbol(foo, Decl(module.d.ts, 0, 26))
16+
17+
=== tests/cases/compiler/some_module.ts ===
18+
export {}
19+
React.foo;
20+
>React.foo : Symbol(foo, Decl(module.d.ts, 0, 26))
21+
>React : Symbol("tests/cases/compiler/module", Decl(module.d.ts, 0, 0), Decl(global.d.ts, 1, 9))
22+
>foo : Symbol(foo, Decl(module.d.ts, 0, 26))
23+
24+
=== tests/cases/compiler/emits.ts ===
25+
console.log("hello");
26+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
27+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
28+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
29+
30+
React.foo;
31+
>React.foo : Symbol(foo, Decl(module.d.ts, 0, 26))
32+
>React : Symbol("tests/cases/compiler/module", Decl(module.d.ts, 0, 0), Decl(global.d.ts, 1, 9))
33+
>foo : Symbol(foo, Decl(module.d.ts, 0, 26))
34+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/compiler/global.d.ts ===
2+
declare global {
3+
>global : typeof global
4+
5+
const React: typeof import("./module");
6+
>React : typeof import("tests/cases/compiler/module")
7+
}
8+
export {};
9+
10+
=== tests/cases/compiler/module.d.ts ===
11+
export as namespace React;
12+
>React : typeof import("tests/cases/compiler/module")
13+
14+
export function foo(): string;
15+
>foo : () => string
16+
17+
=== tests/cases/compiler/some_module.ts ===
18+
export {}
19+
React.foo;
20+
>React.foo : () => string
21+
>React : typeof import("tests/cases/compiler/module")
22+
>foo : () => string
23+
24+
=== tests/cases/compiler/emits.ts ===
25+
console.log("hello");
26+
>console.log("hello") : void
27+
>console.log : (message?: any, ...optionalParams: any[]) => void
28+
>console : Console
29+
>log : (message?: any, ...optionalParams: any[]) => void
30+
>"hello" : "hello"
31+
32+
React.foo;
33+
>React.foo : () => string
34+
>React : typeof import("tests/cases/compiler/module")
35+
>foo : () => string
36+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// @strict: true
2+
// @module: esnext
3+
// @moduleResolution: node
4+
// @target: es2018
5+
// @filename: global.d.ts
6+
declare global {
7+
const React: typeof import("./module");
8+
}
9+
export {};
10+
11+
// @filename: module.d.ts
12+
export as namespace React;
13+
export function foo(): string;
14+
15+
// @filename: some_module.ts
16+
export {}
17+
React.foo;
18+
19+
// @filename: emits.ts
20+
console.log("hello");
21+
React.foo;

0 commit comments

Comments
 (0)