title: Mapping a union of objects to another union of objects with a generic using `Extract`
body: <p>Let's say I have <code>Multi</code>, a type consisting of a union of objects:</p>
  <pre class="lang-js prettyprint-override"><code>interface MultiA {
      type: 'multi-a',
  }
  interface MultiB {
      type: 'multi-b',
  }
  type Multi = MultiA | MultiB;
  </code></pre>
  <p>And I have another type <code>Ext</code>, consisting of a union of objects that extend upon the first ones in different ways:</p>
  <pre class="lang-js prettyprint-override"><code>interface ExtA extends MultiA {
      foo: string
  }
  interface ExtB extends MultiB {
      bar: string
  }
  type Ext = ExtA | ExtB;
  </code></pre>
  <p>I want to map a value of type <code>Multi</code> to <code>Ext</code> while adding the values required by <code>ExtA</code> or <code>ExtB</code>.
  Example:</p>
  <pre class="lang-js prettyprint-override"><code>function mapTypes&lt;K extends Multi['type']&gt;(
      val: Extract&lt;Multi, { type: K }&gt;
  ): Extract&lt;Ext, { type: K }&gt; {
      if (val.type === 'multi-a') {
          return {
              ...val,
              foo: '',
          }
      } else {
          return {
              ...val,
              bar: '',
          }
      }
  }
  </code></pre>
  <p>I expect the <code>Extract&lt;Multi, { type: K }</code> to map to the return type <code>Extract&lt;Ext, { type: K }&gt;</code> without problems since <code>K</code> is the same.</p>
  <p>However, as part of the error message shows (<a href="https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgLIFcA2ZgEFkDeAUMqcmAJ4AOEAXMgOQC2WOAtHAwDREC+RoSLEQoM2YACFCJMpRr1mrYGwBG3PkTmilyALxol+AD4HxEgNxEB4aPCTIAogA8w+CC4ggAJgGdTOfGIyZBgAe1D6HzAoUABzDUFbEUcXKXdIbz8xHCkgshU4KEjouI0tFLA9CuMKiysYdBAEHFCQZCY4KgAVaggfAB4AaWR0z19-YABtBi0GAF0APgAKADc4THpnaMQwfuzgLkJyXvph3gWASk2XKB3+rcOCY-lkM4XpYOAYZFX1gDpyrogYwWOIOAwLh9gmQoBAwOgoG08tDoX80WtMDwUSiwhFGOpsch+MFeCNMD4UMjobD4YioYTSGi-hisQzSAUivjWSjiWR+LwgA" rel="nofollow noreferrer">Typescript Playground Link</a>):</p>
  <blockquote>
  <p>Type 'Extract&lt;MultiA, { type: K; }&gt; &amp; { foo: string; }' is not assignable to type 'Extract&lt;ExtB, { type: K; }&gt;</p>
  </blockquote>
  <p>Typescript tries to test with <code>MultiA</code> and <code>ExtB</code>, which would imply that it tests with<code>K = 'multi-a'</code> and <code>K = 'multi-b'</code> at the same time.</p>
  <p>I guess the <code>Extract</code> type is insufficient here, as it is not being resolved early enough?
  What is the alternative here?</p>