microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.74k stars 12.46k forks source link

allowJs cross-file "go do declaration" / "find references" for `exports.foo =` missing some references #43508

Open cspotcode opened 3 years ago

cspotcode commented 3 years ago

Bug Report

Summary: "find references" and "go to declaration" misses references across files when using allowJs exports.foo = foo;-style exports and const {foo} = require(-style imports.

🔎 Search Terms

go to declaration find all references checkjs allowjs

🕗 Version & Regression Information

⏯ Playground Link

This cannot be demonstrated in the Bug Workbench, so I have created a Stackblitz reproduction linked to github. However, Stackblitz is also unable to reproduce it for some reason.

https://stackblitz.com/edit/typescript-repro-1 https://github.com/cspotcode/repros-stackblitz/tree/allowjs-declarations

💻 Code

// src/index.js
// BUG: "Go to definition" on foo shows "no definition found for foo"
// TS 4.0.5 BUG: "Go to definition" links to the first `foo` in `exports.foo = foo;`, whereas I believe it should link to `async function foo` to match .ts checking behavior.
// GOOD: "Find references" includes `exports.foo = foo;` from libfoo.js
// BUG: "Find references" does not include `async function foo` nor `foo()` from libfoo.js
const {foo} = require('./libfoo');

// GOOD: "Go to definition" on foo jumps to `async function foo` in libfoo.js
// GOOD: "Find references" includes `exports.foo = foo;`
// BUG: "Find references" does not include `async function foo` nor `foo()` from libfoo.js
foo();
// src/libfoo.js
// BUG: "Find references" on the local `foo` in this file does not include anything from `index.js`
// BUG: "Find references" on the `foo` in `exports.foo` in this file does not include anything; jumps to self.
// GOOD: "Go to definition" on the `foo` in `exports.foo` in this file jumps to `async function foo`

exports.foo = foo;
/** jsdoc here */
async function foo() {}

foo();

🙁 Actual behavior

"Find references" on foo is missing references from other files. The BUG: comments in the example enumerate exactly what is wrong.

🙂 Expected behavior

"Go to definition" for all foo identifiers should link to async function foo() "Find references" for any foo identifiers should list all references in both .js files.

cspotcode commented 3 years ago

I updated the "version and regression info" which was wrong.

cspotcode commented 3 years ago

We talked about this a bit on the Community Discord. Here is a link in case it's helpful: https://discord.com/channels/508357248330760243/508357248330760249/826853657982533634