title: Different return types based on optional function parameter - Typescript
body: <p>I have a function that is a wrapper for <code>axios.request</code>. </p>
  
  <p>I send a Message type along with config so that I can create a new Message with the <code>response.data</code>. </p>
  
  <p>I have multiple types of Messages, so I am creating a generic <code>TMessage</code> type to handle this:</p>
  
  <pre><code>public request&lt;TMessage extends BaseMessage&lt;TMessage&gt;&gt;(
      config: Axios.AxiosXHRConfig&lt;any&gt;, 
      messageType: {new (message: string): TMessage}
  ): Promise&lt;TMessage&gt; {
      return new Promise((resolve, reject) =&gt; {
          axios.request(config).then((response: Axios.AxiosXHR&lt;any&gt;) =&gt; {
              try {
                  let message = new messageType(response.data);
                  resolve(message);
              } catch (err) {
                  reject(err);
              }
          }, reject);
      });
  }
  </code></pre>
  
  <p>I can now request with a message type and know what type of response I am getting:</p>
  
  <pre><code>RestClient.request(config, SomeMessage).then((response: SomeMessage) =&gt; {
    // response is of type SomeMessage, I have intellisense to help
    resolve(response);
  });
  </code></pre>
  
  <p>I want to make this messageType optional, as some requests don't have a useful response and don't need to be instantiated into a new message.</p>
  
  <p>Is there a way in TypeScript to do this? The following code uses Union Types and compiles, but it does not enforce the messageType to match the return type, making it a bit redundant.</p>
  
  <p>I want a <code>Promise&lt;TMessage&gt;</code> return type if messageType is supplied. Otherwise I want a <code>Promise&lt;Axios.AxiosXHR&lt;any&gt;&gt;</code> return type</p>
  
  <pre><code>public request&lt;TMessage extends BaseMessage&lt;TMessage&gt;&gt;(
      config: Axios.AxiosXHRConfig&lt;any&gt;, 
      messageType?: {new (message: string): TMessage}
  ): Promise&lt;TMessage | Axios.AxiosXHR&lt;any&gt;&gt; {
    ...
  </code></pre>
  
  <p>-</p>
  
  <pre><code>RestClient.request(config, SomeMessage).then((response: OtherMessage) =&gt; {
    // this compiles, ideally it should complain about the mismatch of message types
    resolve(response);
  });
  </code></pre>