Skip to content
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

Error when accessing properties on globalThis with the same name of a global variable #58345

Open
nicolo-ribaudo opened this issue Apr 28, 2024 · 4 comments
Labels
Bug A bug in TypeScript Help Wanted You can do this
Milestone

Comments

@nicolo-ribaudo
Copy link

πŸ”Ž Search Terms

globalThis redefined error script property does not exist

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

https://www.typescriptlang.org/play/?noImplicitAny=false&ts=5.5.0-beta#code/DYUwLgBAlgdgbgQ2FAJgRggXggc2AewCMkAVACygGcA6WRZdAbgChRIBPLXA44cq2vCSo0LNhABeXPEVIUadYSgBMLIA

πŸ’» Code

let invalid1 = globalThis.invalid1;
let y = globalThis.invalid1;
let z = globalThis.invalid2;

πŸ™ Actual behavior

Property 'invalid1' does not exist on type 'typeof globalThis'.

πŸ™‚ Expected behavior

It should either complain about both invalid1 and invalid2, or neither

Additional information about the issue

It only happens in scripts and not in modules (if I add export {}, there are no reported errors).

@RyanCavanaugh
Copy link
Member

I think what you should actually be seeing here is a circularity error

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Help Wanted You can do this labels May 2, 2024
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone May 2, 2024
@nicolo-ribaudo
Copy link
Author

nicolo-ribaudo commented May 3, 2024

let invalid1 = 1 doesn't define globalThis.invalid1, so there is no circularity going on (it only happens with var).

Note that the code above has actually valid use cases. I spotted it while doing

let SuppressedError = globalThis.SuppressedError ?? class SuppressedError extends Error {
  // ...
}

@Strapazzon
Copy link

Hello @nicolo-ribaudo.

Attempting to use the variable before declaration will result in a ReferenceError. This is known as the "temporal dead zone," where the variable exists in the scope but cannot be accessed.

But, When you declare a variable with var, the variable declaration is "hoisted" (or "raised") to the top of your current scope. This means that, regardless of where you declared the variable in the code, JavaScript treats it as if you had declared it at the beginning of the scope. However, only the declaration is hoisted, not the initialization. Therefore, if you try to access the variable before initializing it, the value will be undefined, but it will not cause an error.

On the other hand, when you declare a variable with let, the declaration is also hoisted, but JavaScript puts these variables in a "temporal dead zone" from the start of the block until the declaration is processed. During this "dead zone", if you try to access the variable, you will receive a ReferenceError.

So, in your case, when you try to do let invalid1 = globalThis.invalid1; without globalThis.invalid1 being defined, invalid1 is undefined. This is not a problem in itself, but if you try to access invalid1 somewhere in the code before this line, you will receive a ReferenceError because of the "temporal dead zone" of let.

However, if you use var instead of let, as in var invalid1 = globalThis.invalid1;, even if globalThis.invalid1 is not defined, invalid1 will simply be undefined and will not cause an error, even if you access invalid1 before this line, thanks to the hoisting of var.

@nicolo-ribaudo
Copy link
Author

nicolo-ribaudo commented May 10, 2024

In the example above no variables are in temporal dead zone -- you can try running that code and it does not error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Help Wanted You can do this
Projects
None yet
Development

No branches or pull requests

3 participants