envalid icon indicating copy to clipboard operation
envalid copied to clipboard

Pick from validators

Open neezer opened this issue 3 years ago • 2 comments

I'm working on a common library for a number of micro services that consume roughly the same environment variables. I'd like to provide definitions for all possible variables in my module, then allow each application to select the definitions they are interested in and ignore the rest.

I was thinking I could do this by wrapping the invocation of envalid.cleanEnv in my own function and pass a list of vars the application was interested in, something like this (the following code does not work FYI):

import { cleanEnv } from 'envalid';

enum Var {
  BindAddr = 'BIND_ADDR',
  BindPort = 'BIND_PORT',
  JwkFile = 'JWK_FILE'
  // ... many more
}

function pick<T, U extends keyof T>(obj: T, keys: U[]): Pick<T, U> {
  const picked = {} as Record<U, any>;

  for (const key of keys) {
    picked[key] = obj[key];
  }

  return picked as Pick<T, U>;
}

export function get<T extends Var>(varsToSelect: T[]) {
  const validators = {
    [Var.BindAddr]: str({ default: 'localhost' }),
    [Var.BindPort]: num({ default: 8000 }),
    [Var.JwkFile]: str()
  };

  return cleanEnv(
    getEnv(),
    pick<typeof validators, T>(validators, vars)
  )
}

I can't figure out how to get the resulting object typed correctly, though. This is what I'm after:

// would be awesome to get this from the argument alone, instead of effectively duplicating the list in the generic argument
const config = get<Var.BindAddr | Var.BindPort>([
  Var.BindAddr,
  Var.BindPort
]);

config.BIND_ADDR //=> should be present of type string
config.BIND_PORT //=> should be present of type number
config.JWK_FILE //=> should be absent

Does this make sense? Is this possible? How can I accomplish this?

neezer avatar Dec 22 '22 19:12 neezer

Have you tried the latest envalid, 8.0.0-alpha.2? Seems to be typed as desired for me when I run your example with it:

Screen Shot 2022-12-29 at 20 53 05

af avatar Dec 30 '22 04:12 af

No, I was trying the latest stable release. I'll give 8.0.0-alpha.2 a try and let you know what I see.

neezer avatar Jan 05 '23 17:01 neezer