title: Pipe function argument type is inferred as any
body: <p>Based on the examples in <a href="https://github.com/microsoft/TypeScript/pull/30215" rel="nofollow noreferrer">Higher order function type inference</a> I tested, how TS resolves function composition types in a <code>pipe</code> function. <code>pipe</code>:</p>
  
  <pre><code>declare function pipe&lt;A extends any[], B, C&gt;(
      ab: (...args: A) =&gt; B, bc: (b: B) =&gt; C): (...args: A) =&gt; C;
  </code></pre>
  
  <p>These are the functions passed to the pipe:</p>
  
  <pre><code>declare function list&lt;T&gt;(a: T): T[];
  declare function box&lt;V&gt;(x: V): { value: V };
  declare function numberBox(x: number[]): { value: number[] }
  </code></pre>
  
  <p>The PR example with the generic <code>box</code> function properly enforces the argument type of <code>listBox(1)</code> to be <code>number</code>:</p>
  
  <pre><code>const listBox = pipe(list, box);  // T is retained
  const x1 = listBox(1); // ... argument properly inferred to  number here
  </code></pre>
  
  <p>But when I use a non-generic <code>number[]</code> box function, the argument gets <code>any</code> type:</p>
  
  <pre><code>const listNumberBox = pipe(list, numberBox)
  const x21 = listNumberBox(1) // argument has any type
  const x22 = listNumberBox("asdfasd") // this shouldn't be possible :/
  </code></pre>
  
  <p>I would assume that inference of a concrete type actually is even "easier" than of a generic type (?), so</p>
  
  <p>1.) why is the argument type of last example inferred to <code>any</code>?</p>
  
  <p>2.) How do I can change the function signature of <code>pipe</code> to enforce all types properly? </p>