title: Why doesn't TypeScript narrow array types?
body: <p>Why is it that TypeScript doesn't narrow the type of arrays?</p>
  <pre class="lang-js prettyprint-override"><code>function test(input: (string | number)[]): string[] {
    // The type of .map(...) reports that it returns string[].
    input = input.map(x =&gt; x.toString())
    // Type error: Type '(string | number)[]' is not assignable to type 'string[]'.
    return input
  }
  </code></pre>
  <p>The workaround is not depending on it narrowing the type by just immediately using or assigning to a fresh variable:</p>
  <pre class="lang-js prettyprint-override"><code>function test(input: (string | number)[]): string[] {
    return input.map(x =&gt; x.toString())
  }
  
  function test(input: (string | number)[]): string[] {
    const newInput = input.map(x =&gt; x.toString())
    return newInput
  }
  </code></pre>
  <p>I did try casting, but in hindsight that obviously only works on use, e.g. <code>return input as string[]</code>, and will not narrow the type, as <code>.map(...)</code> already returns the correctly narrowed type.</p>
  <p>It feels counter intuitive to me having to do these workarounds. <strong>Why is it that TypeScript cannot narrow this array type and are there better workarounds available?</strong></p>
  <p>I did look into the official documentation and looked at similar questions on Stack Overflow, but unless I have overlooked something, I haven't seen this particular question answered with anything else than just to reassign.</p>
  <p>It is what I am doing in my own code for now, but I just wish I knew why it is as it is and if I can do better.</p>
  <pre><code>&gt; tsc --version                                                                                                                                                                                                                                                                              
  Version 4.2.3
  </code></pre>