I have an object that depends on an environment variable, so it can only be resolved at runtime. Is there a way to tell VSCode intellisense how to resolve it, or to ignore that part of the object?
Example:
const specInventory = {
'London': {
speaker: 'JBL'
},
};
module.exports = {
//many other properties
speaker:'LG',
...specInventory[process.env.LOCATION]
};
After this module is imported, I cannot "go to definition" of any of the properties of this file/object, which makes sense since intellisense doesn't know what my properties will be (everything works as expected when the code is running).
I am aware of JSDoc comments. For larger files that solution does not seem to be convenient. Even if I autogenerate the comments, I cannot be sure my colleagues will...
Is there any way to tell Intellisense go to default declaration of the property, ignore the override, or anything else to be able to navigate to this file?
...specInventory[process.env.LOCATION] //intellisense-ignore-line.. :D
P.S. the environment variable is declared in .env file, if that makes any difference...
Thank you in advance.
One way we can deal with this is to tell IntelliSense what we expect the property access specInventory[process.env.LOCATION]
to return using a JSDoc comment.
Expanding on your example:
const specInventory = {
'London': {
speaker: 'JBL'
},
};
/** @type {specInventory[keyof specInventory]} */
const locationSpecInventory = specInventory[process.env.LOCATION];
module.exports = {
//many other properties
speaker:'LG',
...locationSpecInventory
};
This tells IntelliSense that the type of locationSpecInventory
will be one of the sub-properties of specInventory
. When requiring this module in another file, I was able to see the type of speaker
as "string".
Thanks to this answer for the obj[keyof obj]
cleverness, which is effectively a "valueof" for an object.
Another option is to explicitly state what process.env.LOCATION
will be, using a JSDoc cast.
const specInventory = {
'London': {
speaker: 'JBL'
},
};
const location = /** @type {'London'} */ (process.env.LOCATION);
module.exports = {
//many other properties
speaker: 'LG',
...specInventory[location]
};
If you only have a few locations, or want to focus on one specifically from your .env
file, this might do just fine, but if you have a bunch of locations, the other approach might be better suited.