microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
163.58k stars 29.02k forks source link

Javascript IntelliSense forgetting type on different placements of decleration and initialisation #80751

Closed schl3ck closed 5 years ago

schl3ck commented 5 years ago

Issue Type: Bug

I currently have no idea, how VSCode this computes as every possibility results in something different. Basically, IntelliSense sometimes forgets the type a variable has in JavaScript.

I've tried to reproduce it in another folder with other files, but I couldn't get reproduce it.

My setup

In my iCloud Drive folder on Windows I have many .js files, some .json files and in the typings folder a scriptable.d.ts file for the global objects that the iOS app Scriptable provides. Also there is a jsconfig.json with

{
    "compilerOptions": {
        "lib": ["es6"]
    }
}

You can find the scriptable.d.ts here: https://github.com/schl3ck/ios-scriptable-types/blob/8f18ed7fd26289967d0858ce9cea32121c43544b/dist/scriptable.d.ts

Complete folder structure ```text iCloud~dk~simonbs~Scriptable │ !template.js │ Akkustand.js │ App kopieren.js │ AppWatcher make publishable.js │ AppWatcher reset starter.js │ AppWatcher View Apps.js │ AppWatcher.js │ AppWatcher.json │ AppWatcher2.json │ Bootstrap Btn&Custm Chckbx CSS.js │ Comment Maker Comments.js │ Comment Maker.js │ Compare Photos.js │ Copy CopyPaste.js │ CopyPaste Analyser old.js │ CopyPaste Analyser.js │ CopyPaste Error Handler.js │ CopyPaste Merger.js │ CopyPaste Parser.js │ CopyPaste plist to bplist.js │ CopyPaste Shortcut Filter.js │ CopyPaste Sort.js │ Create Gist.js │ FH zu Teamup.js │ File Manager new.js │ File Manager old.js │ FileManger Images.js │ Get User Agent.js │ Ignored Promises.js │ Ignored WebView Requests.js │ Import Script from Gist.js │ import-moment.js │ jsconfig.json │ Notification Sounds.js │ Quick Timer.js │ Remove Notification.js │ Request Sniffer.js │ Run Script in Notification.js │ Text Tools.js │ Untitled Script 1.js │ Untitled Script 2.js │ Untitled Script 3.js │ Untitled Script 4.js │ Untitled Script 5.js │ Untitled Script.js │ View Html File.js │ View Html.js │ View JSON.js │ View System Fonts.js │ Water Reminder old.js │ Water Reminder.js │ What is shared.js │ Würfelpoker.js │ xkcd.js │ ~arrayExtensions.js │ ~BetterRequest.js │ ~CallbackHandler.js │ ~chooseItems.js │ ~notificationManager.js │ ~require.js │ ~textInput.js │ ~timeDiff.js │ ~Timer.js │ ~update script.js │ ~utilities.js │ ├───lib │ csv2json.js │ moment.js │ resemble.js │ ├───publish │ import-moment.scriptable │ ├───typings │ scriptable.d.ts │ ├───Würfelpoker │ 0.PNG │ 1.PNG │ 10.png │ 11.png │ 12.png │ 13.png │ 14.png │ 2.PNG │ 3.PNG │ 4.PNG │ 5.PNG │ 6.png │ 7.png │ 8.png │ 9.png │ └───.Trash │ AppWatcher 1.js │ clipboard.history.json │ cloudSettings │ extensions.json │ FH zu Teamup.js │ import-moment.js │ keybindings.json │ keybindingsMac.json │ Quick Timer 2.js │ settings.json │ snippets_javascript.json │ Untitled Script 5.js │ Untitled Script.js │ VIM Commands.md │ └───iCloud~dk~simonbs~Scriptable │ └───.Trash │ AppTicker 10.json │ AppTicker 11.json │ AppTicker 12.json │ AppTicker 13.json │ AppTicker 14.json │ AppTicker 2.json │ AppTicker 3.json │ AppTicker 4.json │ AppTicker 5.json │ AppTicker 6.json │ AppTicker 7.json │ AppTicker 8.json │ AppTicker 9.json │ AppTicker.json │ AppWatcher 2.js │ AppWatcher 2.json │ AppWatcher 3.js │ AppWatcher 3.json │ AppWatcher 4.js │ AppWatcher 4.json │ AppWatcher 5.js │ AppWatcher v1.0.2.js │ AppWatcher v1.0.scriptable │ AppWatcher.js │ AppWatcher.json │ Bugs with colors.js │ Comment Maker 2.js │ Comment Maker.js │ Compare Images 2.js │ Compare Images.js │ CopyPaste Intent Parser.js │ Html Debugger.js │ import-moment.js │ import-moment.scriptable │ moment 2.js │ moment 3.js │ moment.js │ moment2.js │ NotificationDoesntWait.js │ Progressbar.js │ Tic Tac Toe.js │ Uni Termine.js │ Untitled Script 1 2.js │ Untitled Script 1 3.js │ Untitled Script 1 4.js │ Untitled Script 1 5.js │ Untitled Script 1.js │ Untitled Script 10.js │ Untitled Script 11.js │ Untitled Script 2.js │ Untitled Script 3.js │ Untitled Script 4.js │ Untitled Script 5.js │ Untitled Script 6.js │ Untitled Script 7.js │ Untitled Script 8.js │ Untitled Script 9.js │ View JSON.js │ Water Reminder old 2.js │ Water Reminder old.js │ Water Reminder.js │ Welcome to Scriptable.js │ ~openInApp.js │ ├───Neuer Ordner └───shared AppWatcher v1.0.scriptable ```

Behaviour

In some files in the root folder, the Scriptable folder in iCloud Drive, IntelliSense forgets the type of a variable. This happens only at the top level scope. As soon as I put the code inside its own scope (regardless if it is a function/if/whatever, as long the code is surrounded by { }), it works again as expected. Also, I can't find a pattern which files are affected, but it is constant in this regard. If it worked once in a file, it will work every time and vice versa.

Video

Also I've found that sometimes the issue is resolved, when I split up the decleration and initialisation of the variable, however this is not shown in the video.

I've not been able to reproduce this issue in another folder (copied scriptable.d.ts and jsconfig.json there).


VS Code version: Code 1.38.0 (3db7e09f3b61f915d03bbfa58e258d6eee843f35, 2019-09-03T21:49:13.459Z) OS version: Windows_NT x64 10.0.17134

System Info |Item|Value| |---|---| |CPUs|AMD A12-9700P RADEON R7, 10 COMPUTE CORES 4C+6G (4 x 2495)| |GPU Status|2d_canvas: enabled
flash_3d: enabled
flash_stage3d: enabled
flash_stage3d_baseline: enabled
gpu_compositing: enabled
multiple_raster_threads: enabled_on
native_gpu_memory_buffers: disabled_software
oop_rasterization: unavailable_off
protected_video_decode: unavailable_off
rasterization: unavailable_off
skia_deferred_display_list: disabled_off
skia_renderer: disabled_off
surface_synchronization: enabled_on
video_decode: enabled
viz_display_compositor: disabled_off
webgl: enabled
webgl2: enabled| |Load (avg)|undefined| |Memory (System)|6.97GB (2.93GB free)| |Process Argv|C:\Users\me\iCloudDrive\iCloud\~dk\~simonbs\~Scriptable| |Screen Reader|no| |VM|0%|
Extensions: none
vscodebot[bot] commented 5 years ago

(Experimental duplicate detection) Thanks for submitting this issue. Please also check if it is already covered by an existing one, like:

mjbvz commented 5 years ago

Thanks for the example code and video.

In your first example where fm is in the top level of the file, can you try running go to definition on fm. Based on the symptoms, I suspect the issue is that there is a global called fm somewhere in another. If that is the case, running go to definition on fm will show multiple definition locations

schl3ck commented 5 years ago

Thank you for your response!

I did what you suggested and it indeed opend another file with a global named fm. I renamed that global and switched back to the original file and run the command again. This time it opend a thrid file with the global fm that had something assigned directly, so it would work normally (as it was the same type FileManager). But Go to Definition never showed me a list of definitions.

What can I do to exclude searching other files? Is there an option in a jsconfig.json maybe? I checked the documentation, but found nothing. After renaming jsconfig.json to something else, Go to Definition took me to the correct definition, but IntelliSense still showed that fm is of type any... And it stopped showing the definitions from my definitions file scriptable.d.ts.

mjbvz commented 5 years ago

You can also try the peek definition command which should list all definitions.

Since it looks like this is caused by globals in other files, there a few ways to fix this:

There's also https://github.com/microsoft/TypeScript/issues/14279 which tracks making our IntelliSense treat each file as an independent unit, even if it's not a module

Closing this as a configuration issue/question

schl3ck commented 5 years ago

Thanks!

The peek definition command also only shows one definition and upon renaming that one it shows another file.

I can't use modules as these files are stand alone "projects". And I can't move these files as they're only found in that folder by the executing application. One possibility would be to make a symlink in another folder but that would be tedious to do for every file in its own folder.

Partly the same reason applies for using include and exclude in the jsconfig.json. I would like to switch between the files and I would have to manually change the files part in my jsconfig.json. But that will do it for now.

The issue you linked would solve my problem! I hope there will be some progress in the near future.