title: Typing compose function in TypeScript (Flow $Compose)
body: <p>In flow there is support for <code>$Compose</code> functions (see <a href="https://github.com/acdlite/recompose/pull/523/files#diff-a3b2ae446242082dc9e5d0161d35703fL136" rel="noreferrer">recompose as example</a>). However, I can't seem to find such a mechanism in typescript. it seems that the best typescript can do is something like <a href="https://github.com/reactjs/redux/blob/master/index.d.ts#L416-L460" rel="noreferrer">https://github.com/reactjs/redux/blob/master/index.d.ts#L416-L460</a>. What's the equivalent to <code>$Compose</code> in Typescript?</p>
  
  <p>EDIT: What I'm trying to accomplish is to type the <code>compose</code> function from <code>recompose</code> or <code>redux</code> such that it's typesafe. In particular, with react higher order components, I want to ensure that the output props of one HOC satisfy the input props of the next HOC. This is my current workaround and seems to work reasonably well - though I was hoping there is a good way to do this natively in typescript.</p>
  
  <pre><code>/** Wraps recompose.compose in a type-safe way */
  function composeHOCs&lt;OProps, I1, IProps&gt;(
    f1: InferableComponentEnhancerWithProps&lt;I1, OProps&gt;,
    f2: InferableComponentEnhancerWithProps&lt;IProps, I1&gt;,
  ): ComponentEnhancer&lt;IProps, OProps&gt;
  function composeHOCs&lt;OProps, I1, I2, IProps&gt;(
    f1: InferableComponentEnhancerWithProps&lt;I1, OProps&gt;,
    f2: InferableComponentEnhancerWithProps&lt;I2, I1&gt;,
    f3: InferableComponentEnhancerWithProps&lt;IProps, I2&gt;,
  ): ComponentEnhancer&lt;IProps, OProps&gt;
  function composeHOCs&lt;OProps, I1, I2, I3, IProps&gt;(
    f1: InferableComponentEnhancerWithProps&lt;I1, OProps&gt;,
    f2: InferableComponentEnhancerWithProps&lt;I2, I1&gt;,
    f3: InferableComponentEnhancerWithProps&lt;I3, I2&gt;,
    f4: InferableComponentEnhancerWithProps&lt;IProps, I3&gt;,
  ): ComponentEnhancer&lt;IProps, OProps&gt;
  function composeHOCs(
    ...fns: Array&lt;InferableComponentEnhancerWithProps&lt;any, any&gt;&gt;
  ): ComponentEnhancer&lt;any, any&gt; {
    return compose(...fns)
  }
  </code></pre>