-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is there a way to use TypeScript to prevent accidental global access? #14306
Comments
The number of times I use The unfortunate problem is that you can end up writing accidentally wrong code if we omit the global declarations (because you might accidentally redeclare global variables) so we'd really need to be able to recognize that there are undesirable properties declared that you don't want to access. |
How about adding a
With it on, if you'd write This would require being able to mark variables such as This would also mean that given the option is |
That's a good idea and typical of JavaScript linting (e.g. the |
@DanielRosenwasser AFAIK TS gives an error when declaring a variable without a
@niieani That would be a very clean UX, I like these two ideas a lot.
Can you help me understand why? Shouldn't the fact that the declaration is ambient (as opposed to exported from a module) be enough to hint to TSC that a name is global?
@blakeembrey That's an interesting idea - I wonder what makes a behavior belong in linterland vs. compilerland, semantically speaking. Perhaps since this sort of mistake causes incorrect behavior, it belongs in TSC rather than TSlint. |
Another name that is tricky, especially when converting old code, is |
workaround is to use once done, you can delete unwanted declarations from say downside though is that you will have to manually update theses files as typescript advances |
@DanielRosenwasser it might worth considering adding an option to mute certain ambient declarations, something like:
|
#1351 is related. |
We ended up editing the Perhaps these globals could be separated in their own lib file that can then be selected by adding, for example, |
Keep running into this with |
Another suggestion is anything inside a defined module doesn't inherit globals (that's the first thing I tried). I gather that may reduce the barrier to doing this so it won't be an all or nothing thing. Maybe combine with
I recall some language doing it like this.. maybe ActionScript or C. |
We have also been bitten by the 'name' thing at Google, and have also been considering patching it out of our lib.d.ts. I think the fix that behaves how TypeScript does is to split the standard library up further so that a project can opt in or out from the global declarations. |
I just had an issue where we refactored a function that called It would be nice if we could whitelist globals inside TSConfig. I don't want accessing anything on the window object without explicitly calling Another option would be to require importing any globals. Not sure where it would import it from, but something like |
i just got hosed by |
as of now the only way is to take ownership of |
how about a new setting or lib to allow these globals ONLY through |
What about creating a separate So users could choose to reference that strict version of the |
Looking for a way to prevent usage (not declaration) of global variables to have proper IoC and DI in place in Angular. E.g. wish to prevent usage of localStorage and force its injection via constructor |
For now, I just have a post-install script that rewrites type definition files for malicious files. rewrite("node_modules/@types/jest/index.d.ts", str => {
return str
.replace(/declare const/g, "export const")
.replace(/declare var/g, "export var")
.replace(/declare function/g, "export function")
}) |
The autocomplete list has nothing to do with my work, I don't know why is there, I don't know what the I don't know why it's so complicated, really. What is on |
|
Yes, you are right, the screenshot has most of the things from I don't know how it does it, but Visual Studio was giving me exactly what I needed at the right time. I use Visual Studio Code since many years now, but I never have a good experience with what it suggests. If Visual Studio would work well with Vue.js I wouldn't be here writing about fixing Code. Sorry for my tone, this is just real feedback, without the feelings it would be just half the feedback. |
Was just also bitten by the |
There is a new TSLint rule that prevents access to certain global vars: https://palantir.github.io/tslint/rules/no-restricted-globals/ |
Still seems like it's something the compiler should be able to handle. |
From the thread most people only want to forbid HTML-extension of global, rather than JavaScript global itself. |
It's not that important what is there, it's what is selected. In Visual Studio is almost like it's reading my mind. With VS Code is like it is only now learning what it should be. For example, in VS if I write We had good IntelliSense in VS in 2005 already. Sorry for my English :) |
No ES runtime starts with "global variables," these are all properties of the global object, therefore this is just a dom lib problem, +1 for dom-strict. |
How do we patch |
If you've installed typescript as a dependency of a project, it will be in |
Picking up from a discussion in 18433, quoting @thw0rted:
I'm not an expert either, so I'd appreciate someone jumping in to confirm: I think the lib check is just for .d.ts files and not on source code files, and a project would need to set This can be seen in DefinitelyTyped, where packages that triple-slash for the dom lib are: auth0-js, bent, fetch-headers, interface-datastore, make-fetch-happen, node-red__editor-client, pdfjs-dist, pdfmake, react-map-gl, requestidlecallback, socket.io, superagent, and xmldom. To avoid duplicate definitions, I think lib.dom.d.ts can be set to triple-slash type reference lib.dom-strict.d.ts, and then just add the globals. |
This is a pretty big footgun. We had a bug released to the wild due to this. |
Adding another real world example to this. My team accidentally had a |
Seriously the sorting is the most important thing. When I program I would like to not have to go trough the hole list of suggestions and pick up where my variable is - ironically it's making me even slower. Just finally sort it. |
The sorting part (of Intellisense) is configurable in your user / workspace preferences. I do think that the best solution for this ticket is to use the linter rule discussed above, but you might want to file a ticket with VSCode or the TS language service to allow users to have an ignore list that removes specific symbols from autocomplete. |
extend the |
Never was a fan of globals, and issues like this don't make me any more of a fan. Would be nice to see some kind of a solution for this. My preferred solution would be to have to explicitly import all globals, although I guess such explicit imports which would be omitted from the generated JS code might not align with TypeScript's goals. An additional problem is that auto-import in VSCode doesn't offer any import suggestions if the symbol's name happens to match some global. One such example is the |
Speaking of autocomplete, I'm using this (maybe someone else also would find it handy): On the right side it also can be |
TypeScript now supports custom DOM library: https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/#lib-node-modules So someone only needs to publish the library without globals. The other way is to take |
Two years later, and my team just got bit by the same issue, but with |
+1 here, the number of times I accidentally autocompleted If you use |
Another option would be to mark globals like |
But isn't completion info is enough for this? and also you can just easily mark them as deprecated as you said and use eslint no-deprecated rule |
eslint is probably the ideal tool for this, the list of globals shared above works great. If someone made an eslint plugin/preset for this that could be kept up to date (and accept optional exclusions), I'd use it. |
@erquhart Try https://eslint.org/docs/latest/rules/no-restricted-globals - just solved my problem, hope it solves yours! |
@shelbyspeegle that's what the recommendation I was referencing does (see here), but it includes a long list of globals. The list itself is really helpful, and could be bundled into a plugin that configures |
It's insane that this issue has been left unfixed for so long. Whoever wrote all those globals into Excluding this with |
@SystemParadox Good grief. Those are actual globals in the DOM API. Even if they aren't put in lib.dom.ts, they still exist as a footgun. If you're going to complain, complain about the actual DOM API (and good luck changing that). |
@david-fong your comment makes absolutely no sense. This is exactly the kind of footgun that typescript should be saving us from. It should not be happily declaring them all so we can shoot ourselves. Of course the DOM API isn't going to change, but it doesn't matter if they're still there in the runtime, typescript should pretend that they don't exist so if you use them by mistake it's flagged as an error. I wouldn't mind if there was a sane way to get the DOM types so I could set this up myself, but short of copying the whole of |
I would love to be able to do that: import type {Window} from "@types/web/module"; // Strawman
declare var window: Window; |
I just spent 2 hours tracking down this issue:
focus()
focus()
, but it should have been callingthis.focus()
window.focus()
shares the same signature as ourfocus()
methodIs there a way to throw a compile time error when implicitly accessing global methods (on
window
,global
, etc.)?If not, a compiler flag would be extremely helpful. I would happily be more explicit about commonly used globals (
window.setTimeout
,window.document
, ...) if it meant I could more easily catch insidious bugs like this one.Full commit here: coatue-oss/slickgrid2@0f8bab3.
The text was updated successfully, but these errors were encountered: