Home > front end >  Generic interface for type
Generic interface for type

Time:10-12

I'm trying to create a generic function that returns a configuration, given an enum. In my packages I'd like to create a getConfiguration method that would return me all the env variables that I need.

So for example :

enum PackageAEnvs {
   API_KEY = "API_KEY"
}

enum PackageBEnvs {
   ADMIN_URL = "ADMIN_URL"
}

Ideally, I would like to do something like this :

const getConfiguration = <T extends string[]> (conf: T): Record<T, string>{
     
  return conf.reduce( (acc, val) => {

    const env = process.env[val];

    if(! env) throw new Error()

    return { ...acc, [val]: env}

  }, {})

}

I would then like to have typescript raising errors if the key does not exist :

const { randomKey} = getConfiguration<PackageAEnvs>() <-- typescript should throw error

I found a way using a type :

type Conf = "K1" | "K2" 


type Config =  {[Property in  Conf]: string}

const getConfig = (): Config  => {

  return {
    K1: "2",
    K2: "2"
  }

}
const { someKey } = getConf() // <-- error

However how can I make this getConfig function generic so it could accept any type ? Is it possible ?

CodePudding user response:

You would want to change your function to this:

const getConfiguration = <T extends object>(conf: T): Record<keyof T, string> => {
  return Object.keys(conf).reduce( (acc, val) => {
    const env = process.env[val];
    if(! env) throw new Error()
    return { ...acc, [val]: env}
  }, {}) as any
}

The function now takes the enum directly as an argument and constructs a Record where the keys are the enum keys. We also use Object.keys(conf) to get those keys at runtime.

const { API_KEY } = getConfiguration(PackageAEnvs)
const { ADMIN_URL } = getConfiguration(PackageBEnvs)

Playground

  • Related