title: TypeScript: Generics type definition for TypedArray
body: <p>I am trying to write a function that expands / shrinks TypedArray by taking an arbitrary TypedArray as an input and returns a new same-typed TypedArray with a different size and copy original elements into it.</p>
  
  <p>For example, when you pass, <code>new Uint32Array([1,2,3])</code> with new size of <code>5</code>, it will return <code>new Uint32Array([1,2,3,0,0])</code>.</p>
  
  <pre><code>export const resize = &lt;T&gt;(
      source: ArrayLike&lt;T&gt;, newSize: number,
  ): ArrayLike&lt;T&gt; =&gt; {
      if (!source.length) { return new source.constructor(newSize); }
      newSize = typeof newSize === "number" ? newSize : source.length;
      if (newSize &gt;= source.length) {
          const buf = new ArrayBuffer(newSize * source.BYTES_PER_ELEMENT);
          const arr = new source.constructor(buf);
          arr.set(source);
          return arr;
      }
      return source.slice(0, newSize);
  };
  </code></pre>
  
  <p>While the code works as expected, TSC is complaining that 1) ArrayType does not have <code>BYTES_PER_ELEMENT</code> and <code>slice</code>, and 2) <code>Cannot use 'new' with an expression whose type lacks a call or construct signature</code> for the statement <code>new source.constructor()</code>.</p>
  
  <p>Is there a way to specify type interfaces for such function that TSC understands my intention?</p>
  
  <p>For 1), I understand ArrayLike does not have interface defined for TypedArray but individual typed array does not seem to inherit from a common class... For instance, instead of using generics, I can use <code>const expand = (source: &lt;Uint32Array|Uint16Array|...&gt;): &lt;Uint32Array|Uint16Array|...&gt; =&gt; {}</code>. But it loses context of returning type being same type of the source array.</p>
  
  <p>And for 2) I am clueless on how to tackle this error. It seems reasonable for TSC to complain that source's constructor is lacking type information. But if I can pass proper type for 1), I presume 2) will be disappeared too.</p>
  
  <p>ref) <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray" rel="noreferrer">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray</a></p>