Skip to content
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

Fxied declaration emit for JS files when module.exports is assigned a non-alias value and when it has extra type members #56243

Conversation

Andarist
Copy link
Contributor

fixes #56229

… a non-alias value and when it has extra type members
@typescript-bot typescript-bot added the For Backlog Bug PRs that fix a backlog bug label Oct 28, 2023
Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

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

This seems like a good solution. I'd like @weswigham to take a look too.

let exports = arrayFrom(getExportsOfSymbol(symbol).values());
const merged = getMergedSymbol(symbol);
if (merged !== symbol) {
exports = concatenate(exports, filter(arrayFrom(getExportsOfSymbol(merged).values()), m => !(getSymbolFlags(resolveSymbol(m)) & SymbolFlags.Value)));
Copy link
Member

Choose a reason for hiding this comment

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

what happens if you don't concatenate+filter? I thought the exports of merged would suffice to replace symbol's exports entirely. If not, what is missing in merged? Would it make more sense to start from merged's exports and add only specific things from symbol?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

what happens if you don't concatenate+filter?

Please see the diff below:

git diff
diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 6ab6160af6..d9084479f3 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -9268,7 +9268,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
                 let exports = arrayFrom(getExportsOfSymbol(symbol).values());
                 const merged = getMergedSymbol(symbol);
                 if (merged !== symbol) {
-                    exports = concatenate(exports, filter(arrayFrom(getExportsOfSymbol(merged).values()), m => !(getSymbolFlags(resolveSymbol(m)) & SymbolFlags.Value)));
+                    exports = arrayFrom(getExportsOfSymbol(merged).values());
                 }
                 return filter(exports, m => isNamespaceMember(m) && isIdentifierText(m.escapedName as string, ScriptTarget.ESNext));
             }
diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance3.js b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance3.js
index 5f23727d23..fb9234b587 100644
--- a/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance3.js
+++ b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance3.js
@@ -23,5 +23,37 @@ module.exports.additional = 20;
 
 
 //// [index.d.ts]
-export let member: number;
-export let additional: 20;
+declare namespace _exports {
+    export { additional };
+}
+declare namespace _exports {
+    let member: number;
+    let additional: 20;
+}
+export = _exports;
+
+
+//// [DtsFileErrors]
+
+
+out/index.d.ts(2,14): error TS2323: Cannot redeclare exported variable 'additional'.
+out/index.d.ts(2,14): error TS2484: Export declaration conflicts with exported declaration of 'additional'.
+out/index.d.ts(6,9): error TS2323: Cannot redeclare exported variable 'additional'.
+
+
+==== out/index.d.ts (3 errors) ====
+    declare namespace _exports {
+        export { additional };
+                 ~~~~~~~~~~
+!!! error TS2323: Cannot redeclare exported variable 'additional'.
+                 ~~~~~~~~~~
+!!! error TS2484: Export declaration conflicts with exported declaration of 'additional'.
+    }
+    declare namespace _exports {
+        let member: number;
+        let additional: 20;
+            ~~~~~~~~~~
+!!! error TS2323: Cannot redeclare exported variable 'additional'.
+    }
+    export = _exports;
+    
\ No newline at end of file
diff --git a/tests/baselines/reference/jsDeclarationsExportAssignmentExpressionPlusSecondary.js b/tests/baselines/reference/jsDeclarationsExportAssignmentExpressionPlusSecondary.js
index 83bf1fb653..32b3b52524 100644
--- a/tests/baselines/reference/jsDeclarationsExportAssignmentExpressionPlusSecondary.js
+++ b/tests/baselines/reference/jsDeclarationsExportAssignmentExpressionPlusSecondary.js
@@ -31,12 +31,50 @@ module.exports.Strings = Strings;
 
 
 //// [index.d.ts]
-export namespace Strings {
+declare namespace _exports {
+    export { Strings };
+}
+declare namespace _exports {
+    export let thing: string;
+    export let also: string;
+    export namespace desc {
+        let item: string;
+    }
+    export { Strings };
+}
+export = _exports;
+declare namespace Strings {
     let a: string;
     let b: string;
 }
-export declare let thing: string;
-export declare let also: string;
-export declare namespace desc {
-    let item: string;
-}
+
+
+//// [DtsFileErrors]
+
+
+out/index.d.ts(2,14): error TS2300: Duplicate identifier 'Strings'.
+out/index.d.ts(10,14): error TS2300: Duplicate identifier 'Strings'.
+
+
+==== out/index.d.ts (2 errors) ====
+    declare namespace _exports {
+        export { Strings };
+                 ~~~~~~~
+!!! error TS2300: Duplicate identifier 'Strings'.
+    }
+    declare namespace _exports {
+        export let thing: string;
+        export let also: string;
+        export namespace desc {
+            let item: string;
+        }
+        export { Strings };
+                 ~~~~~~~
+!!! error TS2300: Duplicate identifier 'Strings'.
+    }
+    export = _exports;
+    declare namespace Strings {
+        let a: string;
+        let b: string;
+    }
+    
\ No newline at end of file
diff --git a/tests/baselines/reference/jsDeclarationsExportDoubleAssignmentInClosure.js b/tests/baselines/reference/jsDeclarationsExportDoubleAssignmentInClosure.js
index 610ded5f10..9bd4e00af5 100644
--- a/tests/baselines/reference/jsDeclarationsExportDoubleAssignmentInClosure.js
+++ b/tests/baselines/reference/jsDeclarationsExportDoubleAssignmentInClosure.js
@@ -27,9 +27,36 @@ function foo() {
 
 
 //// [index.d.ts]
+declare namespace _exports {
+    export { m as methods };
+}
 declare function _exports(o: any): any;
 declare namespace _exports {
     export { m as methods };
 }
 export = _exports;
 declare function m(): void;
+
+
+//// [DtsFileErrors]
+
+
+out/index.d.ts(2,19): error TS2300: Duplicate identifier 'methods'.
+out/index.d.ts(6,19): error TS2300: Duplicate identifier 'methods'.
+
+
+==== out/index.d.ts (2 errors) ====
+    declare namespace _exports {
+        export { m as methods };
+                      ~~~~~~~
+!!! error TS2300: Duplicate identifier 'methods'.
+    }
+    declare function _exports(o: any): any;
+    declare namespace _exports {
+        export { m as methods };
+                      ~~~~~~~
+!!! error TS2300: Duplicate identifier 'methods'.
+    }
+    export = _exports;
+    declare function m(): void;
+    
\ No newline at end of file

Would it make more sense to start from merged's exports and add only specific things from symbol?

Maybe. Some time has past since I was investigating this and it is a little bit blurry to me at this point. Based on the diff above though we can't do that - we could only add more this way and with the diff above we already return too much.

Perhaps a different fix can be figured out though.

let exports = arrayFrom(getExportsOfSymbol(symbol).values());
const merged = getMergedSymbol(symbol);
if (merged !== symbol) {
exports = concatenate(exports, filter(arrayFrom(getExportsOfSymbol(merged).values()), m => !(getSymbolFlags(resolveSymbol(m)) & SymbolFlags.Value)));
Copy link
Member

Choose a reason for hiding this comment

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

I think this could potentially have the same symbol in both exports and the merged exports through some complicated aliasing. In such a case, it'd behoove us to deduplicate them. Maybe we could just add 'em both to a Set and then arrayifying it? The deduplicate array helper is... icky - definitely not for things as potentially large as a symbol export table.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i pushed out the requested change

@weswigham
Copy link
Member

@typescript-bot run dt
@typescript-bot test top100
@typescript-bot perf test public
@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jan 10, 2024

Heya @weswigham, I've started to run the public perf test suite on this PR at 4bba29b. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jan 10, 2024

Heya @weswigham, I've started to run the tarball bundle task on this PR at 4bba29b. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jan 10, 2024

Heya @weswigham, I've started to run the diff-based top-repos suite on this PR at 4bba29b. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jan 10, 2024

Heya @weswigham, I've started to run the parallelized Definitely Typed test suite on this PR at 4bba29b. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jan 10, 2024

Hey @weswigham, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/159400/artifacts?artifactName=tgz&fileId=F63FB762B6CAA5B7CE44F4D91F62ED67FA043DA081E701ACB92580981CDE47D002&fileName=/typescript-5.4.0-insiders.20240110.tgz"
    }
}

and then running npm install.


There is also a playground for this build and an npm module you can use via "typescript": "npm:@typescript-deploys/pr-build@5.4.0-pr-56243-5".;

@typescript-bot
Copy link
Collaborator

@weswigham
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
mui-docs - node (v20.5.1, x64)
Memory used 1,735,237k (± 0.00%) 1,735,225k (± 0.00%) ~ 1,735,213k 1,735,240k p=0.228 n=6
Parse Time 6.83s (± 0.15%) 6.84s (± 0.72%) ~ 6.77s 6.91s p=0.681 n=6
Bind Time 2.43s (± 1.06%) 2.42s (± 1.27%) ~ 2.38s 2.47s p=0.518 n=6
Check Time 52.43s (± 0.49%) 52.59s (± 0.38%) ~ 52.43s 52.93s p=0.296 n=6
Emit Time 0.15s (± 3.36%) 0.15s (± 0.00%) ~ 0.15s 0.15s p=0.174 n=6
Total Time 61.84s (± 0.42%) 62.00s (± 0.30%) ~ 61.77s 62.28s p=0.298 n=6
self-build-src - node (v20.5.1, x64)
Memory used 2,683,410k (± 5.14%) 2,658,729k (± 5.35%) ~ 2,575,798k 2,923,284k p=0.810 n=6
Parse Time 5.00s (± 0.87%) 4.98s (± 0.93%) ~ 4.92s 5.02s p=0.520 n=6
Bind Time 2.00s (± 1.39%) 1.99s (± 0.84%) ~ 1.96s 2.01s p=0.625 n=6
Check Time 32.04s (± 0.31%) 32.06s (± 0.22%) ~ 31.94s 32.13s p=0.936 n=6
Emit Time 2.87s (± 1.74%) 2.85s (± 1.35%) ~ 2.81s 2.91s p=0.257 n=6
Total Time 41.93s (± 0.38%) 41.89s (± 0.17%) ~ 41.79s 42.00s p=0.173 n=6
self-compiler - node (v20.5.1, x64)
Memory used 419,047k (± 0.02%) 419,085k (± 0.02%) ~ 418,988k 419,224k p=0.575 n=6
Parse Time 2.88s (± 0.46%) 2.88s (± 0.65%) ~ 2.84s 2.89s p=0.934 n=6
Bind Time 1.14s (± 0.78%) 1.14s (± 0.66%) ~ 1.13s 1.15s p=0.798 n=6
Check Time 14.12s (± 0.22%) 14.10s (± 0.35%) ~ 14.06s 14.19s p=0.258 n=6
Emit Time 1.05s (± 1.20%) 1.05s (± 1.11%) ~ 1.04s 1.07s p=0.801 n=6
Total Time 19.18s (± 0.24%) 19.17s (± 0.26%) ~ 19.13s 19.27s p=0.568 n=6
vscode - node (v20.5.1, x64)
Memory used 2,828,100k (± 0.00%) 2,828,067k (± 0.00%) ~ 2,828,047k 2,828,087k p=0.173 n=6
Parse Time 10.72s (± 0.39%) 10.73s (± 0.20%) ~ 10.70s 10.75s p=0.748 n=6
Bind Time 3.43s (± 0.29%) 3.42s (± 0.37%) ~ 3.40s 3.43s p=0.152 n=6
Check Time 56.28s (± 0.36%) 56.04s (± 0.45%) ~ 55.87s 56.50s p=0.128 n=6
Emit Time 16.25s (± 0.47%) 16.18s (± 0.54%) ~ 16.08s 16.30s p=0.226 n=6
Total Time 86.68s (± 0.31%) 86.37s (± 0.29%) ~ 86.15s 86.75s p=0.092 n=6
webpack - node (v20.5.1, x64)
Memory used 390,748k (± 0.00%) 390,785k (± 0.01%) ~ 390,728k 390,842k p=0.575 n=6
Parse Time 3.31s (± 0.38%) 3.31s (± 0.41%) ~ 3.28s 3.32s p=1.000 n=6
Bind Time 1.43s (± 0.72%) 1.42s (± 0.72%) ~ 1.41s 1.44s p=0.560 n=6
Check Time 12.74s (± 0.16%) 12.76s (± 0.17%) ~ 12.73s 12.79s p=0.413 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 17.48s (± 0.11%) 17.49s (± 0.19%) ~ 17.45s 17.53s p=0.685 n=6
System info unknown
Hosts
  • node (v20.5.1, x64)
Scenarios
  • mui-docs - node (v20.5.1, x64)
  • self-build-src - node (v20.5.1, x64)
  • self-compiler - node (v20.5.1, x64)
  • vscode - node (v20.5.1, x64)
  • webpack - node (v20.5.1, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

Developer Information:

Download Benchmarks

@typescript-bot
Copy link
Collaborator

Hey @weswigham, the results of running the DT tests are ready.
Everything looks the same!
You can check the log here.

@typescript-bot
Copy link
Collaborator

@weswigham Here are the results of running the top-repos suite comparing main and refs/pull/56243/merge:

Something interesting changed - please have a look.

Details

chakra-ui/chakra-ui

4 of 28 projects failed to build with the old tsc and were ignored

packages/components/tsconfig.build.json

  • error TS5056: Cannot write file '/mnt/ts_downloads/chakra-ui/packages/components/dist/types/menu/menu.stories.d.ts' because it would be overwritten by multiple input files.
    • Project Scope

@sandersn sandersn merged commit e769725 into microsoft:main Jan 11, 2024
19 checks passed
@Andarist Andarist deleted the fix/js-dts-module-exports-non-alias-with-type-members branch January 11, 2024 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Backlog Bug PRs that fix a backlog bug
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Invalid .d.ts generated from JSDoc if module.exports is assigned not an identifier
4 participants