Skip to content

Commit 57f975c

Browse files
committed
CommonJS imports support destructuring+property access
Fixes #40578 for prettier
1 parent 0310b53 commit 57f975c

File tree

4 files changed

+35
-45
lines changed

4 files changed

+35
-45
lines changed

src/compiler/checker.ts

+22-9
Original file line numberDiff line numberDiff line change
@@ -2439,10 +2439,11 @@ namespace ts {
24392439
}
24402440

24412441
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration | VariableDeclaration, dontResolveAlias: boolean): Symbol | undefined {
2442-
if (isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) {
2443-
const name = (getLeftmostAccessExpression(node.initializer.expression) as CallExpression).arguments[0] as StringLiteral;
2444-
return isIdentifier(node.initializer.name)
2445-
? resolveSymbol(getPropertyOfType(resolveExternalModuleTypeByLiteral(name), node.initializer.name.escapedText))
2442+
const commonJSPropertyAccess = getCommonJSPropertyAccess(node)
2443+
if (commonJSPropertyAccess) {
2444+
const name = (getLeftmostAccessExpression(commonJSPropertyAccess.expression) as CallExpression).arguments[0] as StringLiteral;
2445+
return isIdentifier(commonJSPropertyAccess.name)
2446+
? resolveSymbol(getPropertyOfType(resolveExternalModuleTypeByLiteral(name), commonJSPropertyAccess.name.escapedText))
24462447
: undefined;
24472448
}
24482449
if (isVariableDeclaration(node) || node.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
@@ -2637,15 +2638,17 @@ namespace ts {
26372638
return result;
26382639
}
26392640

2640-
function getExportOfModule(symbol: Symbol, specifier: ImportOrExportSpecifier | BindingElement, dontResolveAlias: boolean): Symbol | undefined {
2641+
function getExportOfModule(symbol: Symbol, specifier: ImportOrExportSpecifier | BindingElement | PropertyAccessExpression, dontResolveAlias: boolean): Symbol | undefined {
26412642
if (symbol.flags & SymbolFlags.Module) {
2642-
const name = specifier.propertyName ?? specifier.name;
2643+
const name = !isPropertyAccessExpression(specifier) && specifier.propertyName || specifier.name;
26432644
if (!isIdentifier(name)) {
26442645
return undefined;
26452646
}
26462647
const exportSymbol = getExportsOfSymbol(symbol).get(name.escapedText);
26472648
const resolved = resolveSymbol(exportSymbol, dontResolveAlias);
2648-
markSymbolOfAliasDeclarationIfTypeOnly(specifier, exportSymbol, resolved, /*overwriteEmpty*/ false);
2649+
if (!isPropertyAccessExpression(specifier)) {
2650+
markSymbolOfAliasDeclarationIfTypeOnly(specifier, exportSymbol, resolved, /*overwriteEmpty*/ false);
2651+
}
26492652
return resolved;
26502653
}
26512654
}
@@ -2659,6 +2662,12 @@ namespace ts {
26592662
}
26602663
}
26612664

2665+
function getCommonJSPropertyAccess(node: Node) {
2666+
if(isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) {
2667+
return node.initializer;
2668+
}
2669+
}
2670+
26622671
function getExternalModuleMember(node: ImportDeclaration | ExportDeclaration | VariableDeclaration, specifier: ImportOrExportSpecifier | BindingElement, dontResolveAlias = false): Symbol | undefined {
26632672
const moduleSpecifier = getExternalModuleRequireArgument(node) || (node as ImportDeclaration | ExportDeclaration).moduleSpecifier!;
26642673
const moduleSymbol = resolveExternalModuleName(node, moduleSpecifier)!; // TODO: GH#18217
@@ -2682,10 +2691,14 @@ namespace ts {
26822691
else {
26832692
symbolFromVariable = getPropertyOfVariable(targetSymbol, name.escapedText);
26842693
}
2685-
26862694
// if symbolFromVariable is export - get its final target
26872695
symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias);
2688-
let symbolFromModule = getExportOfModule(targetSymbol, specifier, dontResolveAlias);
2696+
2697+
const commonJSPropertyAccess = getCommonJSPropertyAccess(node)
2698+
let symbolFromModule = getExportOfModule(targetSymbol, commonJSPropertyAccess || specifier, dontResolveAlias);
2699+
if (commonJSPropertyAccess && symbolFromModule) {
2700+
symbolFromModule = getPropertyOfType(getTypeOfSymbol(symbolFromModule), name.escapedText);
2701+
}
26892702
if (symbolFromModule === undefined && name.escapedText === InternalSymbolName.Default) {
26902703
const file = find(moduleSymbol.declarations, isSourceFile);
26912704
if (canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias)) {

tests/baselines/reference/jsDeclarationsTypeReferences2.errors.txt

-23
This file was deleted.

tests/baselines/reference/jsDeclarationsTypeReferences2.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,4 @@ export declare const o: {
3838
m: number;
3939
};
4040
//// [index.d.ts]
41-
export const thing: any;
41+
export const thing: number;

tests/baselines/reference/jsDeclarationsTypeReferences2.types

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
=== tests/cases/conformance/jsdoc/declarations/index.js ===
22
const{ a, m } = require("./something").o;
3-
>a : any
4-
>m : any
3+
>a : number
4+
>m : number
55
>require("./something").o : { a: number; m: number; }
66
>require("./something") : typeof import("tests/cases/conformance/jsdoc/declarations/something")
77
>require : any
88
>"./something" : "./something"
99
>o : { a: number; m: number; }
1010

1111
const thing = a + m
12-
>thing : any
13-
>a + m : any
14-
>a : any
15-
>m : any
12+
>thing : number
13+
>a + m : number
14+
>a : number
15+
>m : number
1616

1717
module.exports = {
18-
>module.exports = { thing} : { thing: any; }
19-
>module.exports : { thing: any; }
20-
>module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": { thing: any; }; }
21-
>exports : { thing: any; }
22-
>{ thing} : { thing: any; }
18+
>module.exports = { thing} : { thing: number; }
19+
>module.exports : { thing: number; }
20+
>module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": { thing: number; }; }
21+
>exports : { thing: number; }
22+
>{ thing} : { thing: number; }
2323

2424
thing
25-
>thing : any
25+
>thing : number
2626

2727
};
2828

0 commit comments

Comments
 (0)