envalid icon indicating copy to clipboard operation
envalid copied to clipboard

Make properties added by accessorMiddleware enumerable

Open jraoult opened this issue 1 month ago • 2 comments

I suspect it is simply an oversight. It would be great to have the property added by accessorMiddleware (e.g., isProduction, isDevelopment, etc.) and to make it enumerable so they can be used with the spread operator and other iteration methods.

I'm happy to provide a pull request if you think this is a good idea.

jraoult avatar Nov 17 '25 17:11 jraoult

To be honest I can't recall if this was intentional or not 😅 I can see pros and cons for making them enumerable:

Pro: object spread (which I think is a big pro, and how I'd expect object spread to work) Con: Object.keys()/entries() – I would expect only the actual env var keys to be considered

I don't have a super strong opinion either way here– would welcome a PR but might need to let it sit for a bit to see what the consensus is and if there are any drawbacks I'm not considering

af avatar Nov 18 '25 04:11 af

@af Yeah, it would defo be a breaking change and require a major version bump if introduced without an option. That said, these properties are in the return type (via CleanedEnvAccessors), and it was unexpected (for me anyway) not to see them when iterating. I don't think there is an official way in TypeScript (or TSDoc) to mark a property as not enumerable, but at least for the current version, it would be nice to document it.

For reference, here's how I work around that for now:

for (const key of Object.getOwnPropertyNames(envs)) {
  // it visit all the properties, even the "accessors"
  envs[key]
}

Then, if/when introducing a major version and if we want to conserve the distinction, a solution would be to go all the way and have a different return value for these computed values.

A tuple-based approach:

const [envs, envAccessors] = cleanEnv(...);

const everything = {...envs, ...envAccessors};

Or a nested non-enumerable extra property:


// all the properties in env but `extra` are enumerable 
const  envs = cleanEnv(...);

// the properties in extra are enumerable
envs.accessors.IsProduction

// so in my case I could do
const everything = {...envs, ...env.accessors};

jraoult avatar Nov 18 '25 08:11 jraoult