Skip to content

In JS, fix property access on imports of aliased exports#24930

Closed
sandersn wants to merge 4 commits into
masterfrom
js/fix-chained-export-access
Closed

In JS, fix property access on imports of aliased exports#24930
sandersn wants to merge 4 commits into
masterfrom
js/fix-chained-export-access

Conversation

@sandersn
Copy link
Copy Markdown
Member

Complete the fix of #24754, fixing the incorrect error when accessing properties on the imported symbol. #24871 fixed the incorrect error when accessing properties on exports in the declaring file:

// @Filename: webpack.js
const version = 1001;
const webpack = {};
exports = module.exports = webpack;
exports.version = version; // incorrect error fixed in #24781

webpack.WebpackOptionsDefaulter = 1111;
// @Filename: use.js
var webpack = require('./webpack')
webpack.version // incorrect error fixed in this PR

Much like merging IIFE JS containers, I have to use intersection to implement the merge of export= and exported properties, because the type of export= could be anything returnable by an IIFE.

@sandersn sandersn requested review from mhegazy and weswigham June 13, 2018 18:21
Comment thread src/compiler/checker.ts Outdated
if (symbol.flags & SymbolFlags.Transient && hasEntries(symbol.exports) && widened.flags & TypeFlags.StructuredType) {
resolveStructuredTypeMembers(widened as StructuredType);
const exports = createSymbolTable();
forEachDeclarationInChain(decl, s => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does this need to be done up-front, or can it be deferred until members are requested in resolveStructuredTypeMembers on the result of this call? The resolveStructuredTypeMembers on the other intersection member (to look for is members to check for things to merge) above leads me to believe that it may be good to do so. AFAIK, we'd need to set a CheckFlag or something on this intersection's symbol (or maybe its anonymous object symbol?) and then move this work into resolveStructuredTypeMembers.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fair enough. I moved resolution to resolveIntersectionTypeMembers, which is still slightly less lazy than it could be -- currently resolveIntersectionTypeMembers doesn't resolve members, just call and index signatures -- but seems like a good improvement.

Except that it now incorrectly applies to a couple of global merged symbols that have nothing to do with module.exports, so I need to fix those. I'll push a commit when I've fixed that problem.

@sandersn
Copy link
Copy Markdown
Member Author

@weswigham All right, want to take a look now that it's delayed until intersection-property-resolution time?

Comment thread src/compiler/checker.ts Outdated
}

function resolveSyntheticJSModuleExportMembers(type: IntersectionType) {
if (type.types.length === 2) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a bad predicate. Intersection types are flattened, so if I have one of these intersections and intersect with a 3rd thing, the members from the js initializer will no longer resolve. (eg, /* @type {typeof jsContainer & MyThing} */)

You probably wanna do the filtering/combining on CheckFlags.SyntheticExportEqual in the main resolveIntersectionTypeMembers block.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Woooooops. Nice catch, I forgot all about that. Upon reflection, I decided that removing duplicates from the intersection members wasn't worth that much work anyway. I think it's OK to have duplicated properties of an intersection in a [probably] rare case like this.

I removed resolveSyntheticJSModuleExportMembers and updated the baselines.

@sandersn
Copy link
Copy Markdown
Member Author

@weswigham Mind taking another look?

@sandersn
Copy link
Copy Markdown
Member Author

This now works; I think I fixed it when I improved the typing of exports.

@sandersn sandersn closed this Aug 16, 2018
@jakebailey jakebailey deleted the js/fix-chained-export-access branch November 7, 2022 17:32
@microsoft microsoft locked as resolved and limited conversation to collaborators Oct 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants