title: TypeScript optional union type
body: <p>I'm importing a config.json file and I'm trying to type the output from it. My app will union <code>default</code> with the correct environment in a function and return that. If an invalid or undefined environment is passed in you will only get the <code>default</code> config returned.</p>
  
  <p>Here is an example config.json file:</p>
  
  <pre><code>{
    "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"
    }
  }
  </code></pre>
  
  <p>Here is the function that gets the specific config for our instance.</p>
  
  <pre><code>import config from "src/js/config/config.json";
  
  export type Environment = keyof typeof config;
  export type EnvironmentConfig = typeof config.default &amp; (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 &amp;&amp; configJSON[env]) {
          localConfig = _.merge(localConfig, configJSON[env]);
      }
      return localConfig;
  }
  </code></pre>
  
  <p><strong>UPDATE 1</strong></p>
  
  <p>I thought the trick here was to add an empty object type into the additional options <code>{}</code>. This will allow it to not specify any additional properties.</p>
  
  <p><code>export type EnvironmentConfig = typeof config.default &amp; ({} | typeof config.dev | typeof config.uat | typeof config.prod);</code></p>
  
  <p>However, this an does not exist error trying to access <code>getForEnv(config, 'uat').endpoint3</code></p>