Skip to content

Commit a682a52

Browse files
authored
module.exports aliases have correct flags (#28303)
* module.exports aliases have correct flags They are marked both as (1) alias and (2) assignment declaration. This fixes alias resolution in cases where multiple module.exports assignments exist, but differ in whether they are aliases or not: ```js function f() { } module.exports = f module.exports = 23 ``` Previously, this construct would fail to resolve the alias `f` because the `export=` symbol would be marked as Alias | Value but not Assignment. This change just adds Assignment so that the assignment declaration alias-following rules apply: you should always follow the alias, regardless of other flags. Also, isAliasSymbolDeclaration needed to be tightened up. Previously, I missed the condition that `module.exports =` aliases required an EntityNameDeclaration on right-hand-side, just like `export default` and `export =` aliases. * Address PR comments 1. Rename test to be more accurate. 2. Always mark module.exports assignments with SymbolFlags.Assignment.
1 parent 8056e2b commit a682a52

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

src/compiler/binder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2418,7 +2418,7 @@ namespace ts {
24182418
const flags = exportAssignmentIsAlias(node)
24192419
? SymbolFlags.Alias // An export= with an EntityNameExpression or a ClassExpression exports all meanings of that identifier or class
24202420
: SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.ValueModule;
2421-
declareSymbol(file.symbol.exports!, file.symbol, node, flags, SymbolFlags.None);
2421+
declareSymbol(file.symbol.exports!, file.symbol, node, flags | SymbolFlags.Assignment, SymbolFlags.None);
24222422
}
24232423

24242424
function bindThisPropertyAssignment(node: BinaryExpression | PropertyAccessExpression) {

src/compiler/utilities.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2490,6 +2490,7 @@ namespace ts {
24902490
// export { x as <symbol> } from ...
24912491
// export = <EntityNameExpression>
24922492
// export default <EntityNameExpression>
2493+
// module.exports = <EntityNameExpression>
24932494
export function isAliasSymbolDeclaration(node: Node): boolean {
24942495
return node.kind === SyntaxKind.ImportEqualsDeclaration ||
24952496
node.kind === SyntaxKind.NamespaceExportDeclaration ||
@@ -2498,7 +2499,7 @@ namespace ts {
24982499
node.kind === SyntaxKind.ImportSpecifier ||
24992500
node.kind === SyntaxKind.ExportSpecifier ||
25002501
node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node) ||
2501-
isBinaryExpression(node) && getAssignmentDeclarationKind(node) === AssignmentDeclarationKind.ModuleExports;
2502+
isBinaryExpression(node) && getAssignmentDeclarationKind(node) === AssignmentDeclarationKind.ModuleExports && exportAssignmentIsAlias(node);
25022503
}
25032504

25042505
export function exportAssignmentIsAlias(node: ExportAssignment | BinaryExpression): boolean {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @allowJs: true
4+
// @checkJs: true
5+
6+
// @Filename: /a.js
7+
////function f() {}
8+
////module.exports = f;
9+
////module.exports = 42;
10+
11+
// @Filename: /b.js
12+
////export const foo = 0;
13+
14+
// @Filename: /c.js
15+
////foo
16+
17+
goTo.file("/c.js");
18+
verify.importFixAtPosition([
19+
`import { foo } from "./b";
20+
21+
foo`]);

0 commit comments

Comments
 (0)