68

When I click an imported variable while holding Cmd on macOS in VS Code (or Ctrl on other platforms), I often end up looking at the TypeScript declaration of that variable.

Is there any way to have VS Code take me to the definition of it instead?

I don't use TypeScript myself, so the feature isn't helpful to me right now.

starball
  • 20,030
  • 7
  • 43
  • 238
damd
  • 6,116
  • 7
  • 48
  • 77
  • Can you provide a small code example. This may a design limitation but it depends on what the code looks like – Matt Bierner Oct 23 '17 at 17:59
  • @MattBierner: A simple example would be when I use `import classNames from 'classnames'`, Cmd-click `classNames` and I'm taken to classnames_v2.x.x.js instead of node_modules/classnames/index.js – damd Oct 24 '17 at 09:08
  • Yes, it sounds like you are running into the limitation I describe in my answer. – Matt Bierner Oct 24 '17 at 17:05

5 Answers5

23

Try Go to source definition

This command will try to jump to the original JavaScript implementation of a function/symbol, even for code under node_modules.

JavaScript is a very dynamic language though, so we can't figure out the source location in every case. If you aren't getting results for a common library, please file an issue against TypeScript so we can investigate adding support


For faster and more accurate results, libraries can bundle declaration maps that map from .d.ts files back to source .ts (or .js) files. However many libraries currently do not include these

Matt Bierner
  • 58,117
  • 21
  • 175
  • 206
  • 5
    The issue is closed now, but it is not fully clear to me if it's supposed to work now or rather a "won't fix" (issue is locked preventing any direct clarification). Any ideas what's the status? – bluenote10 May 05 '19 at 13:41
  • The behavior I described is the expected behavior. The main improvement since 2017 is support for [declaration maps](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html#new---declarationmap). I've updated the answer to include info about that – Matt Bierner Dec 03 '19 at 02:32
  • @bluenote10 I guess it's a "won't fix" and I'm very sad about it. What is so hard about just following the import? I just want to see the export that's imported. – ThaJay Sep 12 '22 at 09:32
  • Absolutely useless, it always throws "no source definitions found", even with a dumb regex I can find it manually, classic Microsoft half-baked crap; the types are in @types/fabric, it shouldn't be that hard to guess that node_modules/fabric is where it should start looking it up! – Ivan Castellanos Mar 29 '23 at 02:22
7

I found a simple solution for this after a lot of searching.

You just need to add "typescript.disableAutomaticTypeAcquisition": true to your project's settings.json (or vscode's global settings).

This will disable the automatic generation of TypeScript definitions and restore the original "Jump to" behaviour of going to the implementation.

Source: https://ianwalter.dev/jump-to-source-definition-instead-of-typescript-definition-in-vs-code (archive.org link)

The author provided the wrong instructions though (false when it should have been true so be careful when you read the post. Re-installing node modules was also not needed.

damd
  • 6,116
  • 7
  • 48
  • 77
Nabil Freeman
  • 376
  • 2
  • 12
  • If I try this for something in node_modules, it goes from showing me the *.d.ts file to "no implementation found" – ThaJay Sep 12 '22 at 09:31
6

VSCode was updated to include a new option Go to Source Definition. If the ts source is available and ts is upgraded to > 4.7 and VSCode to > 1.67 it should work.

Many library authors do not include the ts source code unfortunately. The package often only consists of the compiled *.js files and the *.d.ts definition files. That makes this new feature of VSCode useless for these packages unfortunately.

This is the original issue: https://github.com/microsoft/TypeScript/issues/6209

And this is an issue for feedback on the new feature. https://github.com/microsoft/TypeScript/issues/49003

ThaJay
  • 1,758
  • 1
  • 19
  • 30
1

Implementation is bundled and transpiled ro javascript and vscode is not able to take you there but instead of it will take you to interface. You can search for references in javascript file or you can clone or form the repo to see the implementation in typescript.

Jorawar Singh
  • 7,463
  • 4
  • 26
  • 39
  • It would be a nice addition if you could tell ts where you put the repo that corresponds to the package. Then `go to source definition` could work for that package. Even better would be if ts and npm together made it possible that the compiler follows a link to the repo and just pulls the source file directly from there. I guess that's going to be science-fiction for a while though. Not because it's technically hard, but because it's hard to get consensus and to get it organised. It may be easier to achieve in plugin form but still sounds complicated – ThaJay Oct 20 '22 at 13:47
0

As other answers have already stated,

You can use the TypeScript: Go to Source Definition command to go to the symbol definition in the JS file (Regardless of any of your tsconfig and whether the package you are requiring/importing things from provides type declaration files, or whether you installed a Definitely Typed package for it or not). This functionality is provided TypeScript and the vscode.typescript-language-features extension (which is built-into / ships out-of-box with VS Code).

VS Code Nightly also currently includes a new setting: "JavaScript: Prefer Go To Source Definition" and corresponding "TypeScript: Prefer Go To Source Definition", which makes "Go To Definition" first attempt going to the Source Definition, and fallback to the typings definition if a source definition cannot be found. (source).

I thought I'd try to give more interesting information that other answers haven't covered yet for fun and profit curiosity's sake (and also explain why this "often" happens to you, but not always):

  1. You can bind that command to a keybinding. It's keybinding command ID is typescript.goToSourceDefinition.

  2. If the package you require or import packages its own type declaration files or you installed a community-maintained type declaration file from the Definitely Typed project, then ctrl+clicking / cmd+clicking into the require/import argument or putting the caret on it and invoking whatever the editor.action.revealDefinition command or editor.action.goToTypeDefinition are bound to (F12 by default for editor.action.revealDefinition) will take you to the type declaration by default.

  3. If the package you require or import doesn't package its own type declarations and you didn't install a types package from the Definitely Typed project, and you modify your tsconfig or jsconfig to set allowJs: true and maxNodeModuleJsDepth: <N>, then ctrl+clicking / cmd+clicking into the require/import argument or putting the caret on it and invoking whatever the editor.action.revealDefinition command or editor.action.goToTypeDefinition command are bound to (F12 by default for editor.action.revealDefinition) will take you to the symbol's definition in the JS file by default (unless you already performed this action at a point when a type declaration file declaration types for symbol was available and have not since reloaded/restarted VS Code or edited your tsconfig/jsconfig file, because it will cache that association in memory (smells like minor bug, but ¯\_( ツ )_/¯)).

  4. The editor.action.revealDeclaration keybinding seems to do nothing here (at the time of this writing). I guess that keybinding is more for languages like C and C++.

Some loosely related release notes sections and user docs (non-exhaustive list (I don't get paid to do this)):

Quoting from that last one:

One of VS Code's longest standing and most upvoted feature requests is to make VS Code navigate to the JavaScript implementation of functions and symbols from external libraries. Currently, Go to Definition jumps to the type definition file (the .d.ts file) that defines the types for the target function or symbol. This is useful if you need to inspect the types or the documentation for these symbols but hides the actual implementation of the code. The current behavior also confuses many JavaScript users who may not understand the TypeScript type from the .d.ts.

While changing Go to Definition to navigate to the JavaScript implementation of a symbol may sound simple, there's a reason why this feature request has been open for so long. JavaScript (and especially the compiled JavaScript shipped by many libraries) is much more difficult to analyze than a .d.ts. Trying to analyze all the JavaScript code under node_modules would be both slow and would also dramatically increase memory usage. There are also many JavaScript patterns that the VS Code IntelliSense engine is not able to understand.

That's where the new Go to Source Definition command comes in. When you run this command from either the editor context menu or from the Command Palette, TypeScript will attempt to track down the JavaScript implementation of the symbol and navigate to it. This may take a few seconds and we may not always get the correct result, but it should be useful in many cases.

See also: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-7.html#go-to-source-definition.

starball
  • 20,030
  • 7
  • 43
  • 238