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

Go to definition not working as expected when typescript definitions are included #39215

Open
politician opened this issue Jun 23, 2020 · 5 comments
Labels
Bug
Milestone

Comments

@politician
Copy link

@politician politician commented Jun 23, 2020

  • VSCode Version: 1.46.1
  • OS Version: macOS Catalina
  • Does this issue occur when all extensions are disabled?: Yes

TLDR; When writing a Typescript package to be consumed by both Javascript and Typescript, "Go to definition" works for one or the other but not for both.

Problem 1

Steps to Reproduce

  1. Given a NPM package that contains type declarations (.d.ts) and no sourcemaps.
  2. When working in a Typescript or a Javascript project importing this package, if I ⌘+click, I am taken to the type declaration. However, I would expect to be taken to the source file and would expect to be taken to type declarations file if I click "Go to type definition".

Current solutions

  • If the module is written in Javascript: Add sourcemaps.
  • If the module is written in Typescript:
    • Removing type declarations from the package solves the issue for Javascript projects but it means the package is no more compatible with Typescript projects! So this is not a viable solution.
    • Adding sourcemaps along with Typescript sources, leads to Problem 2 below.

Problem 2

Steps to Reproduce

  1. Given a NPM package that contains its Typescript source, compiled Javascript, type declarations and sourcemaps.
  2. When working with a Typescript project that imports this package, if I ⌘+click, I am taken to the source file in Typescript. All is good as expected.
  3. When working with a Javascript project that imports this package, if I ⌘+click, I am still taken to the Typescript source file. However, this is not an expected behavior as I am coding in Javascript, so if I want to debug the code, I'd be lost and have to learn Typescript and setup a Typescript compiler.
    The expected behavior should be to take me to the compiled Javascript (which is what I am actually importing in my project).

Currently, there is no way to control this behaviour, because VS Code probably uses the same algorithm to detect type declarations for Javascript and Typescript.

Possible solutions

  1. VS Code's responsibility: Detect if the project is Javascript and if the source file being taken to is Typescript, then ignore typings. This has the advantage of requiring zero configuration.
  2. Package publisher's responsibility: Introduce a typescript entry in package.json to include type declarations (and maps) to be used only for Typescript. This has the advantage of letting the package publisher decide what they want to do instead of the consumer.
  3. Package consumer's responsibility: Do not pick up type declarations if they are specifically excluded in jsconfig.json
    {
      "exclude": ["./node_modules/npm-package/types"]
    }
    
  4. Package consumer's responsibility: Introduce a new jsconfig.json entry useTypeDeclarations that can be set to false.

Current alternative solution for Problem 1 & 2

  1. The package publisher shall create two subfolders, one for type declarations and one for the compiled Javascript code
  2. The package consumer must import directly the subfolder containing the code instead of the generic package name

package.json

...
"name": "npm-package",
"types": "types/index.d.ts",
"main": "js/index.js",

Project code

import { x, y, z } from "npm-package/js";

This solution has a few downsides that I am aware of:

  • This is not a common way of consuming NPM packages
  • In the case of hybrid packages that supports several module types (CommonJS, ES6, etc.), it means the consumer has to choose which one to use while many tools (Webpack, Rollup, Parcel, ...) would have made the decision for him.

Related discussions

@mjbvz mjbvz transferred this issue from microsoft/vscode Jun 23, 2020
@mjbvz mjbvz removed their assignment Jun 23, 2020
@politician
Copy link
Author

@politician politician commented Jun 25, 2020

@yume-chan Both of these "duplicates" didn't come with any solution. These comments are talking about the problem but nobody reacted.

This is a real problem, please read my initial post: as a package publisher, there is NO WAY for me to publish a package where "go to definition" will work correctly for both JS and TS. And there are some solutions that I proposed in my initial post.

@politician
Copy link
Author

@politician politician commented Jun 25, 2020

@mjbvz This is not a Typescript issue, this is a VS Code issue as far as I am aware
Typescript definitions/sourcemaps work perfectly. The issue is that VS Code is using them for Javascript

@RyanCavanaugh
Copy link
Member

@RyanCavanaugh RyanCavanaugh commented Jun 25, 2020

@incorrupt VS Code asks TS where to go in both cases; I believe the bug is on our end

@RyanCavanaugh RyanCavanaugh added the Bug label Jun 25, 2020
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Jun 25, 2020
@politician
Copy link
Author

@politician politician commented Jun 26, 2020

@RyanCavanaugh

  • is VS Code asking TS where to look for the type declarations + source maps?
  • is VS Code passing the context of the project (wether the user is using TS or not)?

If both are true, then I can see how this is TS responsibility.
And in this case I can only think of a solution that involves generating two sourcemaps: one for JS projects pointing to the compiled code, one for TS projects pointing to the source code.

What do you have in your mind?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants