8 ms·
VS Code to autocomplete JavaScript class 'this' properties automatically
- ajeet_dhaliwal 9y agothis is great. But seriously, this is my setup for 75% of my work, Visual Studio Code with JS, excited to see this little feature in action.
- k__ 9y agoI was blown away how well VSC interacts with JS, especially autocompletion via imports.
- projectramo 9y agoCan someone explain why this (can't stop those puns) is a big deal? 1. I mean why hasn't it existed before? Surely an editor can figure out which object you're in and auto-complete this on the basis of that. 2. If it is hard for some reason, how did they do it?
- _sdegutis 9y agoThe value depends on how you call the function at runtime which requires much deeper code analysis than something like syntax highlighting.
- brlewis 9y agoI'm interested as to whether they did deep code analysis or just added the (not strictly correct, but not terrible) assumption that `this` refers to an instance of the class you're defining. Unfortunately this article is light on links to original source material.
- mattbierner 9y agoNo we don’t do that. In TypeScript code ‘this’ is typed, and we can infer the type of this for classes and ES5 classes in JS. However we don’t analyze calls to ‘.call’ or ‘.apply’ to infer the type of ‘this’ in a given function.
- vbezhenar 9y agoI think that the best editing experience would be editor combined with debugger. JavaScript is a dynamic language, a lot of autocompletes before run is just guesses. But if you're running program and stopped it at that line, you know all available objects and their properties, so autocomplete would be perfect. It would require a bit different development style, but it might worth it.
- DougBTX 9y agoChrome's development tools actually allow saving changes to the JS files AFAIK, or going the other way around, it is possible to debug JS running in the browser from VS Code using the devtools-protocol: https://github.com/ChromeDevTools/devtools-protocol https://github.com/ChromeDevTools/devtools-protocol
- chatmasta 9y agoProblem is enumerating all the possible code paths that could break at the current line.
- seanmcdirmid 9y agoIf you just want a heuristic, having one value is really useful. Polymorphism is rather rarely used anyways.
- dentemple 9y ago1. Unlike with other languages, the value of the "this" object depends on the context in which it was called 2. From what I can tell, VS Code DOESN'T solve it. It only autocompletes the "this" object under certain circumstances (I could be wrong on this last point, since I haven't played around with it first hand)
- koolba 9y agoIs this new feature specific to vanilla JS classes? I've been using autocomplete for Typescript classes in VS Code for as far back as I can remember.
- supergreg 9y agoEdit: I misinterpreted the question at first. I guess in TS you declare a class' properties explicitly while in javascript it is usually done in the constructor. The feature must be related to these dynamic properties. Original answer below. This[0] page says this problem can be also seen in Typescript. But TS has the arrow function as a class method feature that in Javascript is only at stage 2 in it's way to standardization, so it's easier to solve there. [0] https://github.com/Microsoft/TypeScript/wiki/'this'-in-TypeScript https://github.com/Microsoft/TypeScript/wiki/'this'-in-TypeS...
- partycoder 9y agoI don't think this title is correct. `this` is the receiver of the function, which can change depending on how the function is invoked, scope, etc.
- deleted 9y ago[deleted]
- irq-1 9y agoThe feature does not know the type of "this". It doesn't complete "this." but rather when you type a member variable it inserts "this.member". ex. type "width" and it replaces it with "this.width".
- brlewis 9y agoGot a link to more info on the feature? This article seems uninformative at best.
- tootie 9y agoNot to be a grump, but if you were using a staticly-typed language with any half-baked IDE 20 years ago, this behavior was available.
- SimeVidas 9y agoAny plans to make JavaScript (the standard) strictly typed? (I know about TypeScript, etc.)
- WorldMaker 9y agoES4 tried. Typescript, Flow, and ActionScript's type annotations all inherit almost directly from ES4 (though each diverged to different paths). I think the next step would be to see someone champion through TC39 the "Python model" where browsers/engines should at least parse and ignore type annotations per spec. Then at least you could pass Typescript/Flow annotated code directly to a browser, even if the browser/engines don't immediately do anything with those extra annotations.
- nojvek 9y agoThis * 1000. I believe there were some proposals but they never made it past strawman proposal. Just interface {}, as Y, and :type annotations in JavaScript would take us very far. On that note, how does one even submit an ecmascript proposal?
- ts330 9y agohard to fathom there's an entire generation of developers out there for whom this is entirely new magic. there's an entire class of problem and suite of (bad) tooling that they're having to grapple with to deal with things that simply aren't issues in statically typed languages.
- davedx 9y agoAs someone who spent a good 8 years doing development in static languages and then the next 8 or so doing mostly JavaScript, I do occasionally miss the superior tooling available in static languages - and yet, I’m more productive in dynamic languages. This isn’t just experience, I occasionally still write Java and Scala code. But dynamic languages are sufficiently more powerful that the trade off with tooling is worth it. In Scala the compile time alone is a massive drag.
- zbentley 9y agoThe most important word in the title is "class". It only does this properly for JS code inside an explicit ES6 class, and, after some cursory testing, doesn't work too well if you bind things to the class at runtime/outside of the main class block. VS code doesn't autocomplete "this" for "old-school" (function-provided "this" objects and manual prototype inheritance etc.) object-orientish JS; it doesn't compute it properly or at all for re-bound "this" (e.g. apply()/bind()). Making autocompletion analysis work for non-straightforward non-ES6 OO javascript is a very hard (maybe impossible even without any "eval"ed code, though I'm not sure) thing to do, so this isn't a ding on VS code: any autocompletion is better than none. That said, if the only way to get good OO-code autocompletion is to reduce the subset of the language/OO models usable to basically "what you could have in Java/C#", it might be a good opportunity to re-evaluate your choice of language. Transpilers for more easily-statically-analyzable languages do exist, after all.
- paulgb 9y ago> ...it might be a good opportunity to re-evaluate your choice of language. Transpilers for more easily-statically-analyzable languages do exist, after all. I find TypeScript does a pretty good job of allowing as much static analysis as you want without preventing you from using all the features of JS that break it if you wish. In an ideal world I'd work in a fully static language that transpiles to JS but the reality is it's usually necessary to deal with legacy JS libraries. I haven't seen a fully static transpiled language deal with that gracefully, but I'd love to be wrong about that!
- zbentley 9y agoWith regards to static-analysis capability as an aid to developer productivity, I agree with you: find the compromise that best suits your preference. With regards to static-analysis capability as a means of ensuring code reliability, I don't agree. Some people (I'm not characterizing you here since I am unsure if this is your position) consider static analyzability to be equivalent to a strong type system or various safety guarantees with regards to making code's behavior verifiable and/or predictable. If you subscribe to that belief, having an 'escape hatch' that lets you use features of a platform that violate the analyzability guarantees is a virtual guarantee of trouble. I'm put in mind of Rust's "unsafe" areas (there are many other examples of this phenomenon): not only do people routinely overuse them (out of ignorance or misplaced, incorrect, and unverified assertions of "elegance" or "performance"), but their existence at all compromises the ability to verify even small subparts of the greater program: https://news.ycombinator.com/item?id=15146330 https://news.ycombinator.com/item?id=15146330 Having analyzability/guarantees with an escape hatch is better than having none at all, but a lot of people don't understand the tradeoff there.
- htsh 9y agoHow does this compare to Webstorm's autocomplete functionality (as it's one of the primary reasons I started using WS years ago)?
- austincheney 9y agoMadness. Code is so much cleaner when developers drop "this" from their code.
- paulgb 9y agoUnlike Java, JavaScript requires "this". Edit: I didn't realize this would be a contentious point! I'm not trying to advocate for any particular style of JavaScript, just making the point that places in Java where "this" can be omitted, in JavaScript it cannot.
- cgdub 9y agoUnlike JavaScript, Java requires classes.
- austincheney 9y agoYou must not be very experienced in this language. I write all my large applications without "this". Thankfully, this isn't Java and OOP is entirely avoidable.
- dentemple 9y agoIt does not. Certain frameworks will encourage more of its use (such as with passing functions-as-props in React), but Javascript itself can support multiple paradigms, with the `this` keyword supporting only some of its messiest parts.
- paulgb 9y agoIs this true even with classes defined with the "class" keyword? I just tried it and I can't access fields without "this."
- austincheney 9y agoClasses are a relatively new feature to the language and certainly aren't required. Classes are a bit troublesome in that lexical scope doesn't directly apply to class parameters, which is why class parameters cannot achieve explicit privacy unlike other references in the language.
- deleted 9y ago[deleted]
- mattbierner 9y agoVS Code JavaScript/Typescript extension dev here Yes this feature is completely obvious in hindsight, so much so that I felt a little silly highlighting that we never did it before. I guess sometimes you just need someone to file a feature request to point this type of thing out Anyways, please try it out in the current VS Code insiders builds and VS Code 1.20 once it is released next week. Lots of much more exciting stuff coming in 1.20 as well
- rictic 9y agoBy itself this isn't very impressive, but there's more context in the wings if you pay careful attention to the TypeScript type system. Take a look at https://github.com/Microsoft/TypeScript/pull/21316 https://github.com/Microsoft/TypeScript/pull/21316 and https://github.com/Microsoft/TypeScript/pull/21496 https://github.com/Microsoft/TypeScript/pull/21496. This, combined with the existing literal types and mapped types, allows the TypeScript compiler to understand a huge set of existing practices in the JavaScript world, and do high quality type inference over code that looks totally untypable. For example, this is a pattern I see a lot: const args = parseCliFlags({ help: { parser: Boolean, description: 'whether to show help', short: 'h', }, custom: { parser: (v: string) => {return {hmmm: 'yes'}}, repeated: true } }); if (args.help) { console.log('help screen!'); } for (const custom of args.custom) { console.log(custom.hmmm); } So we produce an args object based on the descriptors passed into parseCliFlags. Specifically, we use the parser function and the repeated field. With the above PRs, this code can be fully type checked: interface Descriptor { readonly parser: (value: string) => any; readonly description?: string; readonly short?: string; readonly repeated?: true; } interface Descriptors { readonly [flag: string]: Descriptor; } type FlagTypes<T> = { [K in keyof T]: FlagTypeOf<T[K]> }; type ReturnTypeOf<V> = V extends (...args: any[])=>infer R ? R : never; type FlagTypeOf<V> = V extends {repeated: true, parser: (val: string)=> infer R} ? R[] : V extends {parser: (val: string)=> infer R} ? R : never; That code is tricky to write, but it only needs to be written once, and submitted to DefinitelyTyped. From that point, every VSCode user could benefit from these typings (they already have this part working today, with typings for your node libraries downloaded automatically from DefinitelyTyped).
- nkkollaw 9y agoPerhaps unrelated, but JavaScript has the most annoying handling of "this" in classes that I've ever seen. I'm constantly typing "bind(this)", while the default case should be that "this" within a class points to the object. I understand backward compatibility, but I wish there was some command I could add at the beginning of the file to make JS behave normally. Kind of like "use strict".