title: Code working in TypeScript 3.3 broken in 3.5+, why?
body: <p>I've just migrated my codebase from TypeScript 3.3 to 3.6 and found that the following code does not compile anymore:</p>
  
  <pre class="lang-ts prettyprint-override"><code>declare const enum Api_Request_Type {
      submit_chat_message = 1,
      pull_chat_messages = 2,
      battle_cheat = 50,
      get_collection_page = 12,
  
  }
  
  type Api_Request = {
      type: Api_Request_Type.submit_chat_message
  
      request: {
          message: string
      }
  
      response: {
          messages: string[]
      }
  } | {
      type: Api_Request_Type.pull_chat_messages
  
      request: {}
  
      response: {
          messages: string[]
      }
  } | {
      type: Api_Request_Type.battle_cheat
  
      request: {
          cheat: string
          selected_unit_id: number
      }
  
      response: {
      }
  } | {
      type: Api_Request_Type.get_collection_page
  
      request: {
          page: number
      }
  
      response: object[]
  }
  
  type Find_By_Type&lt;Union, Type&gt; = Union extends { type: Type } ? Union : never;
  type Find_Request&lt;T&gt; = Find_By_Type&lt;Api_Request, T&gt;["request"]
  type Find_Response&lt;T&gt; = Find_By_Type&lt;Api_Request, T&gt;["response"]
  
  
  function api_request_callback&lt;T extends Api_Request_Type&gt;(type: T, data: Find_Request&lt;T&gt;, callback: (res: Find_Response&lt;T&gt;) =&gt; void): void {
      fetch("api" + type, {
          method: "POST",
          body: JSON.stringify(data),
      }).then(data =&gt; data.json()).then(data =&gt; {
          callback(data as Find_Response&lt;T&gt;);
      });
  }
  
  async function api_request&lt;T extends Api_Request_Type&gt;(type: T, data: Find_Request&lt;T&gt;): Promise&lt;Find_Response&lt;T&gt;&gt; {
      return new Promise&lt;Find_Response&lt;T&gt;&gt;((resolve) =&gt; {
          api_request_callback(type, data, (abc) =&gt; {});
      });
  }
  </code></pre>
  
  <p>And the error for it:</p>
  
  <pre><code>Argument of type '(abc: (Find_By_Type&lt;{ type: Api_Request_Type.submit_chat_message; request: { message: string; }; response: { messages: string[]; }; }, T&gt; | Find_By_Type&lt;{ type: Api_Request_Type.pull_chat_messages; request: {}; response: { messages: string[]; }; }, T&gt; | Find_By_Type&lt;...&gt; | Find_By_Type&lt;...&gt;)["response"]) =&gt; void' is not assignable to parameter of type '(res: (Find_By_Type&lt;{ type: Api_Request_Type.submit_chat_message; request: { message: string; }; response: { messages: string[]; }; }, T&gt; | Find_By_Type&lt;{ type: Api_Request_Type.pull_chat_messages; request: {}; response: { messages: string[]; }; }, T&gt; | Find_By_Type&lt;...&gt; | Find_By_Type&lt;...&gt;)["response"]) =&gt; void'.
    Types of parameters 'abc' and 'res' are incompatible.
      Type 'Find_By_Type&lt;{ type: Api_Request_Type.submit_chat_message; request: { message: string; }; response: { messages: string[]; }; }, T&gt;["response"] | Find_By_Type&lt;{ type: Api_Request_Type.pull_chat_messages; request: {}; response: { messages: string[]; }; }, T&gt;["response"] | Find_By_Type&lt;...&gt;["response"] | Find_By_Type&lt;....' is not assignable to type 'Find_By_Type&lt;{ type: Api_Request_Type.submit_chat_message; request: { message: string; }; response: { messages: string[]; }; }, T&gt;["response"] &amp; Find_By_Type&lt;{ type: Api_Request_Type.pull_chat_messages; request: {}; response: { messages: string[]; }; }, T&gt;["response"] &amp; Find_By_Type&lt;...&gt;["response"] &amp; Find_By_Type&lt;....'.
        Type 'Find_By_Type&lt;{ type: Api_Request_Type.submit_chat_message; request: { message: string; }; response: { messages: string[]; }; }, T&gt;["response"]' is not assignable to type 'Find_By_Type&lt;{ type: Api_Request_Type.submit_chat_message; request: { message: string; }; response: { messages: string[]; }; }, T&gt;["response"] &amp; Find_By_Type&lt;{ type: Api_Request_Type.pull_chat_messages; request: {}; response: { messages: string[]; }; }, T&gt;["response"] &amp; Find_By_Type&lt;...&gt;["response"] &amp; Find_By_Type&lt;....'.
          Type '{ messages: string[]; }' is not assignable to type 'Find_By_Type&lt;{ type: Api_Request_Type.submit_chat_message; request: { message: string; }; response: { messages: string[]; }; }, T&gt;["response"] &amp; Find_By_Type&lt;{ type: Api_Request_Type.pull_chat_messages; request: {}; response: { messages: string[]; }; }, T&gt;["response"] &amp; Find_By_Type&lt;...&gt;["response"] &amp; Find_By_Type&lt;....'.
            Type '{ messages: string[]; }' is not assignable to type 'Find_By_Type&lt;{ type: Api_Request_Type.get_collection_page; request: { page: number; }; response: object[]; }, T&gt;["response"]'.
              Type '{ messages: string[]; }' is not assignable to type 'object[]'.
                Type 'Find_By_Type&lt;{ type: Api_Request_Type.submit_chat_message; request: { message: string; }; response: { messages: string[]; }; }, T&gt;["response"]' is not assignable to type 'Find_By_Type&lt;{ type: Api_Request_Type.get_collection_page; request: { page: number; }; response: object[]; }, T&gt;["response"]'.
                  Type 'Find_By_Type&lt;{ type: Api_Request_Type.submit_chat_message; request: { message: string; }; response: { messages: string[]; }; }, T&gt;' is not assignable to type 'Find_By_Type&lt;{ type: Api_Request_Type.get_collection_page; request: { page: number; }; response: object[]; }, T&gt;'.
                    Type 'Find_By_Type&lt;{ type: Api_Request_Type.submit_chat_message; request: { message: string; }; response: { messages: string[]; }; }, T&gt;["response"]' is not assignable to type 'object[]'.
                      Type '{ messages: string[]; }' is missing the following properties from type 'object[]': length, pop, push, concat, and 25 more.
  </code></pre>
  
  <p>The error is rather cryptic due to it containing all the type information, but basically it's saying that there is a type mismatch between the <code>abc</code> in <code>(abc) =&gt; {}</code> and the <code>res: FindResponse&lt;T&gt;</code> in the <code>api_request_callback</code> signature. This code used to compile in 3.3 and makes sense to me why it would.</p>
  
  <p>I'm sure the error is legit but I just don't understand why and how would I go about fixing it.</p>