Skip to content

Commit c161c22

Browse files
authored
Avoid crashing when a source file is attempted to merge with another declaration (microsoft#21494)
1 parent dfe8cf1 commit c161c22

6 files changed

Lines changed: 151 additions & 0 deletions

src/compiler/checker.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20273,6 +20273,8 @@ namespace ts {
2027320273
case SyntaxKind.ClassDeclaration:
2027420274
case SyntaxKind.EnumDeclaration:
2027520275
return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue;
20276+
case SyntaxKind.SourceFile:
20277+
return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue | DeclarationSpaces.ExportNamespace;
2027620278
// The below options all declare an Alias, which is allowed to merge with other values within the importing module
2027720279
case SyntaxKind.ImportEqualsDeclaration:
2027820280
case SyntaxKind.NamespaceImport:
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
tests/cases/compiler/file1.ts(5,1): error TS2708: Cannot use namespace 'Library' as a value.
2+
tests/cases/compiler/file2.ts(1,8): error TS2440: Import declaration conflicts with local declaration of 'Lib'.
3+
tests/cases/compiler/file2.ts(6,12): error TS2694: Namespace 'Lib' has no exported member 'Bar'.
4+
5+
6+
==== tests/cases/compiler/file1.ts (1 errors) ====
7+
export namespace Library {
8+
export type Bar = { a: number };
9+
}
10+
var x: Library.Bar; // should work
11+
Library.foo; // should be an error
12+
~~~~~~~
13+
!!! error TS2708: Cannot use namespace 'Library' as a value.
14+
==== tests/cases/compiler/file2.ts (2 errors) ====
15+
import * as Lib from './file1';
16+
~~~~~~~~
17+
!!! error TS2440: Import declaration conflicts with local declaration of 'Lib'.
18+
namespace Lib { // should fail to merge
19+
export const foo: string = "";
20+
}
21+
Lib.foo; // should work
22+
var x: Lib.Bar; // should be an error
23+
~~~
24+
!!! error TS2694: Namespace 'Lib' has no exported member 'Bar'.
25+
export { Lib }
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//// [tests/cases/compiler/namespaceMergedWithImportAliasNoCrash.ts] ////
2+
3+
//// [file1.ts]
4+
export namespace Library {
5+
export type Bar = { a: number };
6+
}
7+
var x: Library.Bar; // should work
8+
Library.foo; // should be an error
9+
//// [file2.ts]
10+
import * as Lib from './file1';
11+
namespace Lib { // should fail to merge
12+
export const foo: string = "";
13+
}
14+
Lib.foo; // should work
15+
var x: Lib.Bar; // should be an error
16+
export { Lib }
17+
18+
//// [file1.js]
19+
"use strict";
20+
exports.__esModule = true;
21+
var x; // should work
22+
Library.foo; // should be an error
23+
//// [file2.js]
24+
"use strict";
25+
exports.__esModule = true;
26+
var Lib;
27+
(function (Lib) {
28+
Lib.foo = "";
29+
})(Lib || (Lib = {}));
30+
exports.Lib = Lib;
31+
Lib.foo; // should work
32+
var x; // should be an error
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/compiler/file1.ts ===
2+
export namespace Library {
3+
>Library : Symbol(Library, Decl(file1.ts, 0, 0))
4+
5+
export type Bar = { a: number };
6+
>Bar : Symbol(Bar, Decl(file1.ts, 0, 26))
7+
>a : Symbol(a, Decl(file1.ts, 1, 23))
8+
}
9+
var x: Library.Bar; // should work
10+
>x : Symbol(x, Decl(file1.ts, 3, 3))
11+
>Library : Symbol(Library, Decl(file1.ts, 0, 0))
12+
>Bar : Symbol(Library.Bar, Decl(file1.ts, 0, 26))
13+
14+
Library.foo; // should be an error
15+
=== tests/cases/compiler/file2.ts ===
16+
import * as Lib from './file1';
17+
>Lib : Symbol(Lib, Decl(file2.ts, 0, 6), Decl(file2.ts, 0, 31))
18+
19+
namespace Lib { // should fail to merge
20+
>Lib : Symbol(Lib, Decl(file2.ts, 0, 6), Decl(file2.ts, 0, 31))
21+
22+
export const foo: string = "";
23+
>foo : Symbol(foo, Decl(file2.ts, 2, 16))
24+
}
25+
Lib.foo; // should work
26+
>Lib.foo : Symbol(Lib.foo, Decl(file2.ts, 2, 16))
27+
>Lib : Symbol(Lib, Decl(file2.ts, 0, 6), Decl(file2.ts, 0, 31))
28+
>foo : Symbol(Lib.foo, Decl(file2.ts, 2, 16))
29+
30+
var x: Lib.Bar; // should be an error
31+
>x : Symbol(x, Decl(file2.ts, 5, 3))
32+
>Lib : Symbol(Lib, Decl(file2.ts, 0, 6), Decl(file2.ts, 0, 31))
33+
34+
export { Lib }
35+
>Lib : Symbol(Lib, Decl(file2.ts, 6, 8))
36+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
=== tests/cases/compiler/file1.ts ===
2+
export namespace Library {
3+
>Library : any
4+
5+
export type Bar = { a: number };
6+
>Bar : Bar
7+
>a : number
8+
}
9+
var x: Library.Bar; // should work
10+
>x : Library.Bar
11+
>Library : any
12+
>Bar : Library.Bar
13+
14+
Library.foo; // should be an error
15+
>Library.foo : any
16+
>Library : any
17+
>foo : any
18+
19+
=== tests/cases/compiler/file2.ts ===
20+
import * as Lib from './file1';
21+
>Lib : typeof Lib
22+
23+
namespace Lib { // should fail to merge
24+
>Lib : typeof Lib
25+
26+
export const foo: string = "";
27+
>foo : string
28+
>"" : ""
29+
}
30+
Lib.foo; // should work
31+
>Lib.foo : string
32+
>Lib : typeof Lib
33+
>foo : string
34+
35+
var x: Lib.Bar; // should be an error
36+
>x : any
37+
>Lib : any
38+
>Bar : No type information available!
39+
40+
export { Lib }
41+
>Lib : typeof Lib
42+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @filename: file1.ts
2+
export namespace Library {
3+
export type Bar = { a: number };
4+
}
5+
var x: Library.Bar; // should work
6+
Library.foo; // should be an error
7+
// @filename: file2.ts
8+
import * as Lib from './file1';
9+
namespace Lib { // should fail to merge
10+
export const foo: string = "";
11+
}
12+
Lib.foo; // should work
13+
var x: Lib.Bar; // should be an error
14+
export { Lib }

0 commit comments

Comments
 (0)