-
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
[Discussion] Better Way to Declare Globals in JavaScript files #15626
Comments
Why is that? Js users are already using dts files from @types; so does not seem totally foreign concept. |
I mean, it's a long time since the C/C++ days when we had to manually write header files. There's no reason to force a programmer to write a file describing a variable that TypeScript's already aware of and understands the typing of. The job of a computer is to do easily-automated tasks for humans. If you are telling a human to do an easily-automated task for a computer, something is seriously wrong. |
The OP suggests using jsdoc. So some one has to write something. Why not in a .d.ts file |
Yes, you can use |
If you don't want to write a /**
* @type {string}
*/
var myString; then later statements like: console.log(myString.toUpperCase()); will be typechecked. Even if you're writing modules, you can add a file containing globals like this to your compilation - just don't write any imports or exports and it should be global scoped as expected. Unfortunately, as far as I'm aware there's no way to patch definitions onto existing types at present using only jsdoc syntax, so for that you'd have to use a |
When discussing the options it would also be good to provide a quick fix for such an error. (we did that in VS Code before we switched to Salsa by providing a quick fix that added eslint global comment /* global var */ to the file) |
I've added some documentation to VSCode on the My main concern with |
Unfortunately, this doesn't work for I'm still not sure how I use types defined in other files at all... |
usejsdoc.org specifies two existing JSDoc tags that could be useful here: |
based on the discussion in #15747, we need to support |
adding globals to window is tracked under #12902 |
As a vanilla-JS user who just started using |
Any movement on this proposal? |
About this, I did not find any ways to add a property to the node global object without modifing the the node anyones as an idea on how to fix that? I would like to be able to document code as simple as |
@xileftenurb I have exact same problem with some code I inherited. Did you find a workaround? |
the only workaround I found is to do at the start of the file who use the global :
and to use the newly created variable in the file |
If you look upthread, they discuss the correct syntax for declaring globals in a ETA: to be clear, I agree with the OP that one shouldn't need to write a |
can you explain how to do this? also partially the problem for me is that someone is using |
This seems to work for me:
The thing to be aware of is that the typings for NodeJS (
This means it's declaring that |
thanks! that seems to be working! |
Apologies that I'm not familiar enough as yet with Typescript but I have a couple of folders in my Node.js app that are actually front-end code and so have radically different globals to the rest of the code. What would be the correct way to make sure I can check them properly? I am reluctant to put a tsconfig.json file in their root folder as those folders are actually made outwardly available via ExpressJS - though I can do so if needed. |
@TotallyInformation you need to make separate projects for frontend vs backend, with their own Further "how do I" questions would probably be better for StackOverflow -- nothing personal, but we're drifting from the original intent of the issue, which is that (IMHO) TypeScript should provide an inline syntax for declaring globals that doesn't require introduction of a separate |
Thanks for the steer @thw0rted. No intent to turn this into a QA session :) |
@TotallyInformation why not? this is very helpful and this issue ranks high in google for the question. mute the thread if you prefer, it is a [Discussion] |
Discussion means that this is the place to debate how best to implement a new or improved feature in Typescript. It does not mean that the thread is open for questions about how to use existing capabilities. If you click the "New Issue" button, you'll see a prompt that includes the text
The presence of a "discussion" tag here does not change that guidance. |
How I can export a class in
If I use |
I'm hoping this still gets some traction. It'd seem like a fairly easy thing to have JS files in your workspace with @global's apply globally like they should; maybe I'm missing some detail here, but VSCode already picks up global functions and classes from various parts of my workspace. Being able to just plop in a @global on a definition and expect it to work as if it's part of globalThis would be amazing/preferred. |
The code that @heroboy posted above is very common in JavaScript programs. A lot of people wrap all the code in the JS file in a self executing function to avoid polluting the global namespace.
You see there is a lot of repetition and the code is not very elegant. But this is the best way I could find to get intellisense in Visual Studio. I hope we will have a better solution in the future based on |
NB: The Flow syntax to do this is (using jQuery as an example):
This can be done inline in any .js file using |
I tried this but it's still not working. Does anyone know how I can get I have tried both of these in a declare var myGlobal: string; interface Window {
myGlobal: string;
} |
Hi @tnguyen14 , I had a similar issue as you. In my experience if your ambient type declaration file contains an Edit: you need to move the |
Thank you!!! Fixed a very painful problem for me. |
I had a similar question on how to declare a global variable whose type is given by some other module. Here is how I do it. import Target from 'path/to/module';
declare global {
var myObj: typeof Target;
} And done! |
I sure do hate necroposting an issue like this, but from what I can tell, it still isn't resolved despite the seven-year-old resolution on using the @var syntax. Why is there still no way to declare global variables using JSDoc? We know the JSDoc syntax, we know the equivalent TS syntax. Why have these not been linked together yet? For context, not that it particularly matters given that both the problem and the solution are fully specified, I'm trying to make a toy Electron project, using their If it's simply a matter of "no one has done the work yet" I'd be delighted to submit a PR for it, but my experience with corporate-owned software projects like this one is that it is 100% futile to submit a PR without someone on the other side ready and waiting to receive it. That plus, the fact that this would be such a simple issue to knock out and yet it's been seven years tells me that the issue isn't getting the work done, the issue is getting it accepted. So? What's the hold-up? Is there anything that can be done to move this along, or is this just a pocket veto by the Typescript team? |
This would be so useful. When writing Custom Elements with JS + JSDoc, I have one file per custom elements, for example for two elements my-element.js
other-element.js where one has a To define type definitions for these elements so that they are visible in DOM APIs, for example so that we get this: const el = document.querySelector('my-element') // type of `el` is `MyElement`
/** @type {MyElement} */
const el2 = el // ok, el is assignable
/** @type {OtherElement} */
const el3 = el // type error, el is not OtherElement but MyElement we would need to write definitions like this if we were using TypeScript files: // my-element.js
class MyElement extends HTMLElement {...}
customElements.define('my-element', MyElement)
declare global {
interface HTMLElementTagNameMap {
'my-element': MyElement
}
} // other-element.js
class OtherElement extends HTMLElement {...}
customElements.define('other-element', OtherElement)
declare global {
interface HTMLElementTagNameMap {
'other-element': OtherElement
}
} But as you know, we can't do this in a JS file using JSDoc. So, what we have to do is double the number of files that we have, so that we can place these definitions in my-element.js
my-element-types.d.ts
other-element.js
other-element-types.d.ts (Note, the names must not be the same, for example If we have 50 elements, now we have to double our files to 100, cluttering up the workspace. It would be great not to have to double the amount of files. An alternative is to stick element definition all in a single file, but then that becomes less portable, for example you can't simply copy/paste files from project to project, but you have to specifically extract pieces of the .d.ts file that has the element defs. Note, in related issues such as
having a more useful comment space for writing TS types could help. For example, picking one of those syntax proposals at random, we could have something like the following in a JS file: // other-element.js
class OtherElement extends HTMLElement {...}
customElements.define('other-element', OtherElement)
/*::
declare global {
interface HTMLElementTagNameMap {
'other-element': OtherElement
}
}
*/ |
Also, .d.ts files might not be supported by vscode in some edge cases (having files without the js extension) : microsoft/vscode#37772
EDIT : To load a d.ts file without the need of a jsconfig file, you can use the following line : /// <reference path="../lib.d.ts"/> |
Problem
Using the new
checkJs
feature, it is currently difficult to tell TypeScript about a global variable:The only way around this that I know is to create a
.d.ts
file that defines these:JavaScript users should not have to write
*.d.ts
files.Possible Approaches
@egamma proposes that may be able to use the
global
comment from ESlint http://eslint.org/docs/user-guide/configuring :/* global var1, var2 */
I'd also be interested to see if we could put type information in a jsdoc somehow, something like:
The text was updated successfully, but these errors were encountered: