title: How can typescript switch cases be narrowed to fit only the narrow return type
body: <p>I want to write a function that maps from some config type to the corresponding service type. Have the following setup that works great to have the right types inferred when calling.</p>
  <p>However typescript does not like the return types in each case statement.
  <a href="https://www.typescriptlang.org/play?#code/FAehAIBUE8AcFNwFcAuBLANgZ2CuiA5AQwCcSB7AdwGV4SA3NAY3gB4BVAOzXM4BpwtBs3gBJACYA%20cAF5wXHp3DwAHinidxWcAG9wWOoxYSAXIMMiJ4AL7gA-PO69wZzvHp0A3LnznhLAHkAM1YhIzFxZTUNLT9wrABtAHIDfwikgF1pOWIyKjCRUIsWLAEC4ylvYDROdRIgohZwAGFeILQAcwBGXWBwfv1iiLMAIlTwrpHva2Bq2roGptbOdo6AJl6BwbTTcDGhtangGbm6xcRy%20B6dPoHxy3EzZdWu5PuKzOnZmrPGi4PNnchrtnp01m9geJPsdZngEHERFhQR1tHJkT0AD4tNpg7xw-5pVEIliY4nwNZVJgYIhYbTUHpoAC2sAw8EZGhQdKG11u-Xew2xK06rxSkMysj2-MmXypNLpGyZLLZHK5aQ2Ny2-JBOPWEJ2UIyEv2aqOJyCSE4THQzg68BQlwAYhRGcjQs0oupNKr4sisJIABRMHVmajNACUIaGwTdevCEky0g1d0oaBQTAAFuBAzqAHRa8RhwFbfpMGmIUVpLpJMwkO1IEhKNyUQRdf1h7zFgalgzgCvhNbV8C1lD1xvwZvUNZtqpbGYnW32oZO8gunX%20nT50ZSkbWdvgMDYsjwK0YaDgIOcLAoEhEGrwSIochkrrAIA" rel="nofollow noreferrer">TS Playground link</a> for this code.</p>
  <pre><code>type NarrowService&lt;Union, ServiceId&gt; = Union extends { serviceId: ServiceId } ? Union : never;
  type ServiceOf&lt;ServiceId extends Services['serviceId']&gt; = NarrowService&lt;Services, ServiceId&gt;;
  
  interface Config1 {
      serviceId: &quot;service1&quot;;
  }
  
  interface Config2 {
      serviceId: &quot;service2&quot;;
  }
  
  class S1 implements Service1 {
      serviceId: Config1['serviceId'] = &quot;service1&quot;;
  }
  class S2 implements Service2 {
      serviceId: Config2['serviceId'] = &quot;service2&quot;;
  }
  
  type ServicesConfigs = Config1 | Config2;
  type Services = Service1 | Service2;
  
  class S1 implements Service1 {
      serviceId: &quot;service1&quot;;
  }
  class S2 implements Service2 {
      serviceId: &quot;service2&quot;;
  }
  
  function getServiceFromConfig&lt;SC extends ServicesConfigs&gt;(config: SC): ServiceOf&lt;SC['serviceId']&gt; {
      switch (config.serviceId) {
          case 'service1': return new S1(); // error: &quot;Type 'S1' is not assignable to type 'ServiceOf&lt;SC[&quot;serviceId&quot;]&gt;'&quot;
          case 'service2': return new S2(); // error: &quot;Type 'S2' is not assignable to type 'ServiceOf&lt;SC[&quot;serviceId&quot;]&gt;'&quot;
  
      }
  }
  
  getServiceFromConfig({serviceId: &quot;service1&quot;}); // Correctly constrained to Service1
  </code></pre>
  <p>Is there some correct way to hint at the mapping inside the switch that I would be able to add? Apologies for the complex case, I could not think of any way to make it simpler than this.</p>