Skip to content

CommonJS imports support destructuring+property access #40702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 24, 2020

Conversation

sandersn
Copy link
Member

CommonJS imports now support destructuring a require that is part of a property access expression:

const { x } = require('m').o

Previously either worked alone but not together:

const o = require('m').o
const { o } = require('m')

Fixes #40578 for prettier; I didn't think anybody did this, so I let the tests fail earlier. Turns out prettier does!

@typescript-bot typescript-bot added For Milestone Bug PRs that fix a bug with a specific milestone labels Sep 22, 2020
// if symbolFromVariable is export - get its final target
symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias);
let symbolFromModule = getExportOfModule(targetSymbol, specifier, dontResolveAlias);

const commonJSPropertyAccess = getCommonJSPropertyAccess(node);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't all this work be under getTargetOfAliasDeclaration (which resolveSymbol eventually calls out to), and not in getExternalModuleMember directly?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the test case below, resolveSymbol is called first on the BindingElement a, which goes to getTargetOfImportSpecifier. Do you mean that function? I put the code in getExternalModuleMember because it seemed similar to the export= code above, and because getExternalModuleMember is called several places.

But looking again, it's only two other places, both exports where this wouldn't apply.

markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false);
return resolved;
}

function getCommonJSPropertyAccess(node: Node) {
if(isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) {
if (isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to commit your suggestion directly but github kept claiming the PR was recently updated =(

Thanks to @weswigham for noticing this. Somehow it passed the linter.
@sandersn sandersn merged commit eac75f3 into master Sep 24, 2020
@sandersn sandersn deleted the commonjs-import-destructuring-property-access branch September 24, 2020 21:43
@ExE-Boss
Copy link
Contributor

ExE-Boss commented Nov 6, 2020

Fun fact: This is also what Node recommends for using the *.promises namespaced APIs before Node v15, which added a large number of */promises alias modules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team For Milestone Bug PRs that fix a bug with a specific milestone
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Commonjs import with destructuring ignores trailing property access
4 participants