title: Typescript type safety in conditional union type switch typing
body: <p>I have a simple function taking a union type and a <code>boolean</code> as parameters and cannot manage to have it be typed by Typescript.</p>
  
  <p>I have this code (<a href="https://www.typescriptlang.org/play/#src=type%20A%20%3D%20&#39;a&#39;%20%7C%20&#39;A&#39;%3B%0D%0A%0D%0Afunction%20g(a%3A%20A)%3A%20string%20%7B%0D%0A%20%20%20%20switch%20(a)%20%7B%0D%0A%20%20%20%20%20%20%20%20case%20&#39;a&#39;%3A%20return%20&#39;&#39;%3B%0D%0A%20%20%20%20%20%20%20%20case%20&#39;A&#39;%3A%20return%20&#39;&#39;%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Afunction%20f1(a%3A%20A%2C%20b%3A%20boolean)%3A%20string%20%7B%0D%0A%20%20%20%20if%20(b)%20%7B%0D%0A%20%20%20%20%20%20%20%20switch%20(a)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20&#39;a&#39;%3A%20return%20&#39;&#39;%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20&#39;A&#39;%3A%20return%20&#39;&#39;%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%20else%20%7B%0D%0A%20%20%20%20%20%20%20%20switch%20(a)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20&#39;a&#39;%3A%20return%20&#39;&#39;%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20&#39;A&#39;%3A%20return%20&#39;&#39;%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Afunction%20f2(a%3A%20A%2C%20b%3A%20boolean)%3A%20string%20%7B%0D%0A%20%20%20%20if%20(b)%20%7B%0D%0A%20%20%20%20%20%20%20%20return%20g(a)%3B%0D%0A%20%20%20%20%7D%20else%20%7B%0D%0A%20%20%20%20%20%20%20%20return%20g(a)%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Afunction%20f3(a%3A%20A%2C%20b%3A%20boolean)%3A%20string%20%7B%0D%0A%20%20%20%20if%20(b)%20%7B%0D%0A%20%20%20%20%20%20%20%20return%20g(a)%3B%0D%0A%20%20%20%20%7D%20else%20%7B%0D%0A%20%20%20%20%20%20%20%20switch%20(a)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20&#39;a&#39;%3A%20return%20&#39;&#39;%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20&#39;A&#39;%3A%20return%20&#39;&#39;%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Afunction%20f4(a%3A%20A%2C%20b%3A%20boolean)%3A%20string%20%7B%0D%0A%20%20%20%20if%20(b)%20%7B%0D%0A%20%20%20%20%20%20%20%20switch%20(a)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20&#39;a&#39;%3A%20return%20&#39;&#39;%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20&#39;A&#39;%3A%20return%20&#39;&#39;%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%20else%20%7B%0D%0A%20%20%20%20%20%20%20%20return%20g(a)%3B%0D%0A%20%20%20%20%7D%0D%0A%7D" rel="nofollow noreferrer">playground here</a>):</p>
  
  <pre><code>type A = 'a' | 'A';
  
  function f(a: A, b: boolean): string {
      if (b) {
          switch (a) {
              case 'a': return '';
              case 'A': return '';
          }
      } else {
          switch (a) {
              case 'a': return '';
              case 'A': return '';
          }
      }
  }
  </code></pre>
  
  <p>The compiler (when <code>strictNullChecks</code> is enabled) tells me <code>Function lacks ending return statement and return type does not include 'undefined'.</code> </p>
  
  <p>I really don't want to add <code>default</code> cases since the goal here is to ensure that when I add new types in <code>A</code> I handle them correctly in <code>f</code>. And I don't see which branch I am missing.</p>
  
  <p>I could fix it by writing (see the linked playground):</p>
  
  <pre><code>function g(a: A): string {
      switch (a) {
          case 'a': return '';
          case 'A': return '';
      }
  }
  
  function f2(a: A, b: boolean): string {
      if (b) {
          return g(a);
      } else {
          return g(a);
      }
  }
  </code></pre>
  
  <p>(Of course in real life I need two different g functions but for the typing issue this is not important).</p>
  
  <p>How can I let typescript compile <code>f</code> without introducing intermediate functions like <code>g</code> ?</p>