Skip to content
Advertisement

Is there any way to make IDEs like VSCode recognize global variables that don’t exist yet? (Node)

So I know the question is probably super confusing but basically I have a file in my node project that when importing one of the exports it will set the value of variable in the global scope as a getter. Basically this means that you can call the same value over and over again and get different results. For example:

magicIncrement.js:

let count = -1;

module.exports = {
  get magicIncrement() {
    Object.defineProperty(global, 'increment', { 
      get: () => {
        count += 1;
        return count;
      },
    });
  },
};

index.js:

let { magicIncrement } = require('./magicIncrement');

console.log( 'increment:', increment );
const test = increment;
console.log('"test"s value doesn't change.')
console.log('test:', test);
console.log('test:', test);
setTimeout(() => {
  console.log('...but "increment"s value always will')
  console.log( 'increment:', increment );
}, 1010);

The result is that increment will increase every time the variable is called.

The issue is that the variable isn’t recognized by the IDE since ‘increment’ technically doesn’t exist as far as VSCode is aware. Is there any way to fix this issue?

P.S. I tried simply setting the export (in this example “magic increment”) as the name of the global variable/getter (in this case “increment”) but it seems like setting a variable in a file (like via destructing as done in index.js) simply cuts the link between global.[var name] and [var name].

Advertisement

Answer

When you’re working in a module system and you’re writing a script, you should generally try to work within the module system whenever possible. Only resort to global pollution when there’s no other option.

Here, you can accomplish what you need by returning the getter on an exported object (not the global object):

let count = -1;
module.exports = {
  get increment() {
    count += 1;
    return count;
  }
};
const theIncrementModule = require('./magicIncrement');
console.log(theIncrementModule.increment);
console.log(theIncrementModule.increment);

But this sort of code is pretty confusing – when writing solid, maintainable code, you shouldn’t try to deliberately hide the fact that a certain getter or property access is carrying out side-effects (such as incrementing a count variable). You can hide it behind abstractions, sure – but don’t try to write confusing and tricky code (like having a getter on the global object) to hide it.

Advertisement