title: how to type define a zip function in typescript
body: <p>Say I want to create a <code>zip</code> function:</p>
  
  <pre class="lang-js prettyprint-override"><code>function zip(arrays){
      // assume more than 1 array is given and all arrays 
      // share the same length
      const len = arrays[0].length;
      const toReturn = new Array(len);
      for (let i = 0; i &lt; len; i++){
          toReturn[i] = arrays.map(array=&gt;array[i]);
      }
      return toReturn;
  }
  
  console.log(zip([
      [1,2,3],
      [4,5,6],
      [7,8,9],
      [10,11,12],
  ]));
  /*
  Output:
  (3) [Array(4), Array(4), Array(4)]
  0: (4) [1, 4, 7, 10]
  1: (4) [2, 5, 8, 11]
  2: (4) [3, 6, 9, 12]
  */
  </code></pre>
  
  <p>In order to type define this function when all arrays hold the same type of elements:</p>
  
  <pre class="lang-js prettyprint-override"><code>    function zip&lt;T&gt;(arrays: T[][]): T[][]{/* codes omited here */}
  </code></pre>
  
  <p>However, when arrays are of different types of elements, I get confused about how to use generic type to finish the type definition.</p>
  
  <pre class="lang-js prettyprint-override"><code>    const zipedResult = zip([[1,2,3],[true,false,true],['a','b','c']]);
      // error raises: Type 'false' is not assignable to type 'number'.(2322)
  </code></pre>
  
  <p>what I want is </p>
  
  <pre class="lang-js prettyprint-override"><code>    [[1,2,3],[true,false,true],['a','b','c']]
  </code></pre>
  
  <p>could be automatically infered as <code>(number|boolean|string)[][]</code> without writing <code>as (number|boolean|string)[][]</code>
  or EVEN
  infered as <code>[number[],boolean[],string[]]</code> and result of <code>zip</code> infered as <code>[number, boolean, string][]</code></p>
  
  <p>How should I correctly type define <code>zip</code> to fullfill such features?</p>