TypeScript optional union type

1.3k views Asked by At

I'm importing a config.json file and I'm trying to type the output from it. My app will union default with the correct environment in a function and return that. If an invalid or undefined environment is passed in you will only get the default config returned.

Here is an example config.json file:

{
  "default" : {
    "endpoint1": "https://example.com",
    "endpoint2": "https://example.com"
  },
  "dev" : {
    "endpoint3": "https://example.com",
    "api_key":"key"
  },
  "uat" : {
    "endpoint3": "https://example.com",
    "api_key":"key"
  },
  "prod" : {
    "endpoint3": "https://example.com",
    "api_key":"key"
  }
}

Here is the function that gets the specific config for our instance.

import config from "src/js/config/config.json";

export type Environment = keyof typeof config;
export type EnvironmentConfig = typeof config.default & (typeof config.dev | typeof config.uat | typeof config.prod);

let localConfig: undefined | EnvironmentConfig;

function getForEnv(configJSON: typeof config, env: Environment | null): EnvironmentConfig {

    // error thrown here because default does not have types from the specific environments.
    // This type should always have default but may also have a specific environment.
    localConfig = configJSON.default;
    if (env !== null && configJSON[env]) {
        localConfig = _.merge(localConfig, configJSON[env]);
    }
    return localConfig;
}

UPDATE 1

I thought the trick here was to add an empty object type into the additional options {}. This will allow it to not specify any additional properties.

export type EnvironmentConfig = typeof config.default & ({} | typeof config.dev | typeof config.uat | typeof config.prod);

However, this an does not exist error trying to access getForEnv(config, 'uat').endpoint3

0

There are 0 answers