title: Automatic detection of object property type based on another property value
body: <p>I am trying to make a 'switcher' of an unknown type coming from a database. Basically, there are certain calculation types that have a different data structure and need to be processed differently depending on the type. My first way to solve the problem was using conditionals:</p>
  <pre class="lang-js prettyprint-override"><code>type CalculationTypes = &quot;add&quot; | &quot;average&quot;
  
  export interface Calculation&lt;T extends CalculationTypes&gt; {
    calculationID: string // unique to all calculations
    type: T
    payload: T extends &quot;add&quot; ? CalculationAdd : CalculationAverage 
  }
  
  interface CalculationAdd {
    addlist: {referenceContainer: string, referenceID: string}[] 
  }
  
  interface CalculationAverage {
    averageList: number[]
  }
  </code></pre>
  <p>This worked - kind of - because the type wasn't being detected later in the script. I had to infer it, which isn't so bad, but I'm sure there's a better way to do it where the transpiler can automatically deduce the type...</p>
  <p>Then later in the script:</p>
  <pre class="lang-js prettyprint-override"><code>    for (const calculation of dbresult.calculations) {
        switch(calculation.type) {
          case &quot;add&quot;:
            const payload = calculation.payload as CalculationAdd // &lt;--- this is what I want it to do automatically.
            /** The transpiler does not detect it. It thinks that payload is of
                type CalculationAdd | CalculationAverage **/
            payload.addList // do stuff works now with type inference
            // do more stuff
            break;
          case &quot;average&quot;:
            const payload = calculation.payload as CalculationAverage
            payload.averageList  // do stuff
            // do more stuff
            break;
        }
      }
  </code></pre>
  <p>Without type inference, typescript gives me the error:</p>
  <pre><code>Property 'addList' does not exist on type 'CalculationAdd | CalculationAverage'.
    Property 'addList' does not exist on type 'CalculationAverage'
  </code></pre>
  <p>So for some reason, typescript has not deduced that it has to be of type CalculationAdd without type inference, even though that's the only possibility given the conditional I set up in the Calculation interface.</p>
  <p>How can I change the way I'm defining these types and interfaces so that typescript automatically deduces them?</p>
  <p>Thanks!</p>