TL;DR: How do you include a tsconfig.json file in Visual Studio 2017 and still have JavaScript intellisense work like it does by default, giving code hints both for your own code and 3rd-party libraries? Is it borked, or do I just need a better understanding of how it works?
Much like jQuery, I would like ubiquitous access to my own JavaScript namespaces across JavaScript and html files with intellisense. How does one achieve this?
EDIT 3:
I reported this issue on developercommunity.visualstudio.com. Please consider up-voting the issue to attract more attention from Microsoft.
EDIT 2:
Currently the "solution" is Resharper, which provides what one would expect straight out-of-the-box. But it's not really ideal at a price of $299/yr/user for something Visual Studio markets it provides itself.
EDIT 1:
In the event that my expectations for JavaScript intellisense in Visual Studio is inaccurate, below is a contrived example of how I expect it to function.
Say I create three TypeScript files in my ./Scripts folder, we'll call them A.ts, B.ts, and C.ts. Each will contain its own namespace:
A.ts
namespace A {
export function f1(s: string) {
return s;
}
}
B.ts
namespace B {
export function f1(n: number) {
return n;
}
}
C.ts
namespace C {
export function f1(b: boolean) {
return b;
}
}
At this point in time one may expect to be able to start seeing intellisense for their newly created namespaces, and indeed, within A.ts, B.ts, and C.ts you begin to see intellisense for those namespaces. Cool.
Unfortunately this doesn't carry over to other places, like /Home/Index.cshtml. Index.cshtml knows nothing about the A, B, or C namespaces. Additionally, .js files know nothing about these namespaces, hence the need for their respective TypeScript Declaration (.d.ts) files.
So we'll go ahead and add our tsconfig.json file to the root of our project and configure it like we do above. If we perform an edit on one of our .ts files and save it, this triggers the compilation of our corresponding .d.ts files into our ./Scripts/out folder. Do we now get intellisense in Index.cshtml and .js files? ...No.
Now you might be thinking these files need to be included in the project in order for Visual Studio to pick them up for intellisense (they're excluded on creation). So you include them in the project. Intellisense? No. jQuery intellisense? No. Perhaps they need to be in the same directory as the file you want to use them in? .....Kind of? I've ran into intellisense being inconsistent like this on a number of occassions:
Somehow we're getting intellisense for our 'A' namespace within our C3.js (note: a JavaScript file), but none of the other ones. What?
Perhaps you think you're on the right track and that you've scored a small victory against the intellisense engine. But then you restart your Visual Studio instance and...
Wait....I just had intellisense for the 'A' namespace. What happened!?
I have no idea. But after messing around for a bit I try placing an import statement at the top of the .js file, and all of a sudden intellisense starts kicking in for the imported files/modules. Huzzah!
And even in Index.cshtml I begin receiving intellisense for our imported namespaces.
The moment I close the .js file with the import statements, though, all of a sudden I lose the intellisense for them in Index.cshtml. Wait...what?? And unlike in JavaScript files, I'm unable to write an import statement to receive intellisense for them:
Or at least... not with my own namespaces:
It's this inconsistent back-and-forth that confuses the heck out of me as to how exactly Visual Studio's JavaScript intellisense actually works. I still don't know if it's just broken or if I need a better understanding of it.
ORIGINAL POST
System
Windows 10
VS2017 15.0.0+26228.10
New JavaScript language service is enabled
I've been fighting to get Visual Studio 2017's JavaScript intellisense to work for me for a couple of days now to no avail. I don't know if something's genuinely wonky with the IDE or if I just don't understand it properly.
My understanding of how VS2017's JS intellisense works is now by typescript definition files, or .d.ts files. Ultimately I would like to get intellisense to help us out with our own TypeScript/JavaScript but right now I'd settle for just having it work consistently within a fresh project.
If I create a new ASP.NET MVC 4.5.2 project, out-of-the-box JS intellisense seems to work fine, and by that I mean I can type a dollar sign ($) either in a .js file or between <script> tags and I properly receive intellisense for jQuery. Awesome. Now, with the ultimate goal in mind of creating TypeScript files (.ts) and having the TypeScript compiler generate our .d.ts files automagically so that we can get rich intellisense for our own code, I wish to introduce a tsconfig.json file to the root of the project in order to configure that.
After creating the tsconfig.json file JS intellisense ceases to function. I type a dollar sign ($) into either a .js file or between <script> tags and I get zero intellisense for jQuery. This was a frustrating experience for a while but then I read this little note found on the linked page above:
NOTE: This feature is disabled by default if using a tsconfig.json configuration file, but may be set to enabled as outlined further below).
"This feature" is in reference to "By default, the Salsa language service will try to detect which JavaScript libraries are in use...in order to provide richer IntelliSense." Ok, so the Salsa language service will not autodetect libraries in use and provide intellisense for them when a tsconfig.json file is present, unless you specifically configure it to do so as "outlined below." At least, that's how I understand it.
If we scroll down the page a little bit and come to the tsconfig file settings we come across a setting for enableAutoDiscovery which "enables the automatic detection and download of definition files as outlined above." It's not super explicit as to what "as outlined above" is in reference to, but I can only assume it's in reference to the previous note indicative of re-enabling Salsa's auto-detection feature to provide rich intellisense. So I include that option in my tsconfig.json file and...no benefit; still no JS intellisense.
As it turns out, typingOptions.enableAutoDiscovery has been renamed to typeAcquisition.enable. Grrrrr. Alright, so we make that change in our tsconfig.json aaaaaaand... still no JS intellisense.
At this point I am able to write my own .d.ts files and Visual Studio's intellisense will pick it up alright (most of the time...), but I still have no intellisense for 3rd-party libraries like jQuery, which is no good.
So far I've landed on the following tsconfig.json file:
{
"compilerOptions": {
"noEmitOnError": true,
"noImplicitAny": false,
"removeComments": false,
"target": "es5",
"declaration": true,
"declarationDir": "./Scripts/out"
},
"compileOnSave": true,
"typeAcquisition": {
"enable": true,
"include": ["jquery"]
},
"include": [
"./Scripts/app/**/*"
],
"exclude": [
"./Scripts/vendors/**/*",
"./Scripts/out/**/*"
]
}
With the TypeScript virtual project in view I can see that my project's .ts files are included as well as jQuery in my %LOCALAPPDATA%\Microsoft\TypeScript\node_modules@types directory.
I was hopeful that with all this in place I would have both intellisense for my own project's .ts files and 3rd-party libraries (at least those specifically included; jQuery only at this point). Alas...no. Still no jQuery intellisense.
Incidentally, if I write an import line for jQuery, all of a sudden I get jQuery intellisense
...interesting. And maybe that makes perfect sense; I haven't messed a whole lot with module imports and how Visual Studio's intellisense handles those, but what I really want is to have intellisense application-wide for both our code and 3rd-party libraries.