title: How to add TypeScript types to destructured parameters using spread syntax?
body: <p>Ignore the fact that this is bad <code>add</code> function. It's a question about using array destructuring with spread syntax in TypeScript.</p>
  
  <p>This is what I'm trying</p>
  
  <pre><code>const add = ([x,...xs]) =&gt; {
    if (x === undefined)
      return 0
    else
      return x + add(xs)
  }
  
  console.log(add([1,2,3])) //=&gt; 6
  </code></pre>
  
  <p>But I have no idea how to add TypeScript types to this. My best guess is to do something like this (most direct translation)</p>
  
  <pre><code>const add = (xs: number[]): number =&gt; {
    if (xs[0] === undefined)
      return 0;
    else
      return xs[0] + add(xs.slice(1));
  };
  
  console.log(add([1,2,3])); // =&gt; 6
  </code></pre>
  
  <p>Both functions work, but in TypeScript I lose the ability to destructure the array parameter and the function body is junked up with a bunch of ugly stuff like <code>xs[0]</code> and <code>xs.slice(1)</code> – even if I abstract these into their own functions, that's besides the point.</p>
  
  <p>Is it possible in add types to destructured spread parameters in TypeScript?</p>
  
  <hr>
  
  <p><strong>What I've tried so far</strong></p>
  
  <p>Something like this works for fixed arrays</p>
  
  <pre><code>// compiles
  const add = ([x,y,z]: [number, number, number]): number =&gt; ...
  </code></pre>
  
  <p>But of course I need variable length array input. I tried this, but it doesn't compile</p>
  
  <pre><code>// does not compile
  const add = ([x, ...xs]: [number, number[]]): number =&gt; ...
  </code></pre>