title: In TypeScript, why can't an async function return a union of type T | Promise<T>?
body: <p>I'm building an API in typescript and some controller actions can be synchronous while others can't.  I'd like to specify a response type like so:</p>
  
  <pre><code>type ActionResult =IHttpActionResult | Promise&lt;IHttpActionResult&gt;;
  </code></pre>
  
  <p>Then, as I'm building actions, when they become promise based, I can just prepend async and be done with it.</p>
  
  <p>But, typescript complains that "the return type of an async function or method must be the global Promise type."</p>
  
  <p>Why can't an async function return a union of <code>T | Promise&lt;T&gt;</code>?</p>
  
  <p>Here's an example:</p>
  
  <pre><code>type StringPromise = Promise&lt;string&gt;;
  
  // These two work as you'd expect
  async function getHello(): Promise&lt;string&gt; {
      return 'hello';
  }
  
  async function getGoodbye(): StringPromise {
      return 'goodbye';
  }
  
  type StringyThingy = string | Promise&lt;string&gt;;
  
  // the next two work as you would expect them to
  function getHoorah(): StringyThingy {
      return 'hoorah!';
  }
  
  function getWahoo(): StringyThingy {
    return new Promise(resolve =&gt; resolve('wahoo'));
  }
  
  // This one results in the error:
  // "the return type of an async function or method must be the global Promise type."
  async function getSadface(): StringyThingy {
    return ':(';
  }    
  </code></pre>
  
  <p>Here are some sample outputs for the code above:</p>
  
  <pre><code>getHello().then(console.log);
  getGoodbye().then(console.log);
  console.log(getHoorah());
  
  // The library I'm using is probably using typeguards for this
  // I'd imagine
  const wahoo = getWahoo();
  if (typeof(wahoo) === 'string') {
    console.log(wahoo);
  } else {
    wahoo.then(console.log);
  }
  </code></pre>