Skip to content

Commit ca840ee

Browse files
committed
Fix name resolution of exports in JS (#27394)
The ad-hoc name resolution rule for `exports` forgets to check the requested meaning. When `getTypeReferenceType` calls` resolveTypeReferenceName` with `Type` only in order to give an error when the program uses a value like a type, it is incorrectly able to resolve `exports` instead of producing an error. Then this incorrect symbol gets treated like an alias, which it isn't, causing the assert. The fix, for now, is to make resolution of `exports` check the requested meaning so that it only resolves when `Value` is requested. This makes the above code an error ("Cannot use the namespace 'exports' as a type."), but I think this is fine for a bug fix. We can decide later if `exports` should behave like other expandos and be a legal type reference. Note that the name actually does resolve correctly, so JS users will get the desired completions. They'll just have an error to suppress if they have checkJs on.
1 parent 8a4b6e0 commit ca840ee

File tree

5 files changed

+52
-1
lines changed

5 files changed

+52
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1466,7 +1466,7 @@ namespace ts {
14661466
if (!result) {
14671467
if (lastLocation) {
14681468
Debug.assert(lastLocation.kind === SyntaxKind.SourceFile);
1469-
if ((lastLocation as SourceFile).commonJsModuleIndicator && name === "exports") {
1469+
if ((lastLocation as SourceFile).commonJsModuleIndicator && name === "exports" && meaning & lastLocation.symbol.flags) {
14701470
return lastLocation.symbol;
14711471
}
14721472
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
tests/cases/conformance/jsdoc/bug27342.js(3,11): error TS2709: Cannot use namespace 'exports' as a type.
2+
3+
4+
==== tests/cases/conformance/jsdoc/bug27342.js (1 errors) ====
5+
module.exports = {}
6+
/**
7+
* @type {exports}
8+
~~~~~~~
9+
!!! error TS2709: Cannot use namespace 'exports' as a type.
10+
*/
11+
var x
12+
13+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
=== tests/cases/conformance/jsdoc/bug27342.js ===
2+
module.exports = {}
3+
>module.exports : Symbol("tests/cases/conformance/jsdoc/bug27342", Decl(bug27342.js, 0, 0))
4+
>module : Symbol(module, Decl(bug27342.js, 0, 0))
5+
>exports : Symbol("tests/cases/conformance/jsdoc/bug27342", Decl(bug27342.js, 0, 0))
6+
7+
/**
8+
* @type {exports}
9+
*/
10+
var x
11+
>x : Symbol(x, Decl(bug27342.js, 4, 3))
12+
13+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
=== tests/cases/conformance/jsdoc/bug27342.js ===
2+
module.exports = {}
3+
>module.exports = {} : typeof import("tests/cases/conformance/jsdoc/bug27342")
4+
>module.exports : typeof import("tests/cases/conformance/jsdoc/bug27342")
5+
>module : { "tests/cases/conformance/jsdoc/bug27342": typeof import("tests/cases/conformance/jsdoc/bug27342"); }
6+
>exports : typeof import("tests/cases/conformance/jsdoc/bug27342")
7+
>{} : {}
8+
9+
/**
10+
* @type {exports}
11+
*/
12+
var x
13+
>x : typeof import("tests/cases/conformance/jsdoc/bug27342")
14+
15+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// @allowJs: true
2+
// @noEmit: true
3+
// @checkJs: true
4+
// @Filename: bug27342.js
5+
module.exports = {}
6+
/**
7+
* @type {exports}
8+
*/
9+
var x
10+

0 commit comments

Comments
 (0)