microsoft / TypeScript

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

Impossible to Automatically Import "assert" module/function #41087

Closed machineghost closed 3 years ago

machineghost commented 3 years ago

TS Template added by @mjbvz

TypeScript Version: 4.1.0-dev.20201013

Search Terms


Issue Type: Bug

Steps to Reproduce:

  1. Use checkJs: true or Typescript to get automatic imports
  2. Type assert
  3. Once VS Code recognizes it as an unknown variable, get the squiggly line under it
  4. Quick fix it and normally (ie. with any other package) you'd be offered the option to automatically import it
  5. ... but you don't

Does this issue occur when all extensions are disabled?: N/A (There's no intellisense at all in that mode).

Also I just want to note that I did try to get this answered on Stack Overflow (and even put up a bounty on the question)! https://stackoverflow.com/questions/63471503/in-vs-code-how-can-i-automatically-import-assert-in-a-react-node-app/64183399

But since no one could solve it, I think it's safe to call this a bug.

VS Code version: Code 1.49.2 (e5e9e69aed6e1984f7499b7af85b3d05f9a6883a, 2020-09-24T16:26:09.944Z) OS version: Linux x64 5.4.0-48-generic

System Info |Item|Value| |---|---| |CPUs|Intel(R) Core(TM) i7-4810MQ CPU @ 2.80GHz (8 x 1596)| |GPU Status|2d_canvas: enabled
flash_3d: enabled
flash_stage3d: enabled
flash_stage3d_baseline: enabled
gpu_compositing: enabled
multiple_raster_threads: enabled_on
oop_rasterization: disabled_off
opengl: enabled_on
protected_video_decode: unavailable_off
rasterization: disabled_software
skia_renderer: enabled_on
video_decode: unavailable_off
vulkan: disabled_off
webgl: enabled
webgl2: enabled| |Load (avg)|2, 2, 2| |Memory (System)|23.40GB (3.38GB free)| |Process Argv|--no-sandbox --unity-launch --crash-reporter-id 9c401b24-b47f-425d-a167-fd18f3576159| |Screen Reader|no| |VM|0%| |DESKTOP_SESSION|mate| |XDG_CURRENT_DESKTOP|MATE| |XDG_SESSION_DESKTOP|mate| |XDG_SESSION_TYPE|x11|
Extensions (18) Extension|Author (truncated)|Version ---|---|--- vscode-sqlite|ale|0.9.0 vscode-styled-jsx|bla|2.0.0 refactor-jsx|chi|0.0.1 jsrefactor|cms|2.20.6 vscode-eslint|dba|2.1.8 githistory|don|0.6.11 EditorConfig|Edi|0.15.1 prettier-vscode|esb|5.7.1 auto-rename-tag|for|0.1.4 vscode-graphql|Gra|0.3.10 debugger-for-chrome|msj|4.12.11 abracadabra|nic|4.8.0 vscode-react-refactor|pla|1.0.5 vscode-javascript-booster|sbu|14.0.1 vscode-markdown-todo|Tom|12.0.1 vscode-status-bar-format-toggle|tom|2.0.0 better-search|tra|0.0.6 local-history|xyz|1.8.1
mjbvz commented 3 years ago

After installing @types/node, I see the following auto imports:

Screen Shot 2020-10-13 at 1 09 39 PM

These are both are auto imports from console.

If I write out assert, I see the correct quick fix suggestion:

Screen Shot 2020-10-13 at 1 10 32 PM
machineghost commented 3 years ago

But isn't the whole idea of checkJs: true that VS code is supposed to be able to infer types?

I mean it figures out imports from my files; why does it need me to give it types for Node's?

MartinJohns commented 3 years ago

checkJs: true enables type checking in JavaScript files. But it needs to know what types exist, and that's why the @types/* packages exist. Without the @types/node package the TypeScript compiler has no awareness of the existence of these types.

machineghost commented 3 years ago

Here's what doesn't make sense to me.

If I make a file called assert.js and give it a default export, or if I have an export const assert = line in a file ... in either case VS Code can infer enough from just that to let me import the function. It literally does not matter what types I use inside that function, or anywhere else in that module: checkjs: true in my config is all that I need to automatically import it.

But with a built-in function that has to be there (to even be running Javascript at the command line at all) ... VS Code can't do what it can do to the file I wrote?

MartinJohns commented 3 years ago

But with a built-in function that has to be there (to even be running Javascript at the command line at all) ...

But it doesn't have to be there, for example it's not available in the browser. By installing the package you make the types of your target ecosystem known.

machineghost commented 3 years ago

Right, but my code doesn't have to be there either. You still haven't answered the core question I'm asking.

When I create const assert = () => ... (without any types defined for it), in a completely arbitrary and random place (/src/some/where/assert.js), VS Code is capable of finding it and inferring its types.

When every Node project ever written keeps the same exact file ... in the same exact place ... VS Code can't find it or infer its types.

But that should be a much easier problem to solve than the assert I create: that is what doesn't make sense here. Why can't VS Code do to a known file what it can do to an unknown one?

RyanCavanaugh commented 3 years ago

But with a built-in function that has to be there (to even be running Javascript at the command line at all)

We don't make assumptions about which environment you're running in. You could be running in node, you could be running in the browser, you could be running in a WebWorker context, you could be running in some other runtime. There is a difference here between which packages are available (which we can tell from the file system) and which environment you're writing an application against, the latter of which there are no real concrete clues to work from.

machineghost commented 3 years ago

You know I have a node_modules folder in my project, no? Just like you know I have a /src/some/where/assert.js ... even though I never told "you" (ie. VS Code)?

RyanCavanaugh commented 3 years ago

Plenty of people are writing browser code that bundles in stuff from node_modules - why do you think react-dom is on npm?

MartinJohns commented 3 years ago

node_modules also contain devDependencies (e.g. typescript or eslint). Doesn't mean it'll be run in a NodeJS environment.

machineghost commented 3 years ago

Right, but whether I put React in node_modules or I make const React = () => ... VS Code finds it ... correct?

In either case, I don't make types for React. In the former I have types in the package written by someone else, but my homemade const React has no types. So again, we have two cases of:

Both of those cases are handled by VS Code. assert is an anomaly: it's literally the only function I know of that VS Code can't infer.

RyanCavanaugh commented 3 years ago

"assert" doesn't come from node_modules/assert, though - it comes from the environmental typings which you haven't informed VS Code of (by installing them)

machineghost commented 3 years ago

Ahhh ... now it finally makes sense, thank you so much for the explanation! I was incorrectly assuming it was in node_modules. So ... to try and state what you told me before more clearly ...

The simple rule is that VS Code can find and infer anything in my project folder ... and what makes assert anomalous is that it's source isn't in my project folder (and thus I need an external mechanism of me providing explicit Node type files)?

RyanCavanaugh commented 3 years ago

More or less. There are a bunch of heuristics we have in place to try to make auto-import only show things we think "should" be in the list and we always recommend trying to write the import manually if you don't see something you expect - either this will fail to resolve (and you'll know something's amiss) or we'll start treating the target module as "in your project" and you should see identifiers from that module show up for future auto-import suggestions.

machineghost commented 3 years ago

Gotcha (and yes I have noticed that last bit before; obviously the incredible type inference feature isn't perfect, and does need "hints" sometimes).

But since I have no idea how those heuristics you describe work, I'm going to keep my understanding at "anything not in my project folder won't be seen by VS Code (without installing types), and anything in-project that's 'normal' (ie. that doesn't cheese off your heuristics) will."

:-D Thanks again!