title: How to type a function that partially applies another function?
body: <p>This is the javascript function I want to provide a JsDoc with type signature for:</p>
  
  <pre><code>function provideExtra(f, extra) {
    return (props, ...args) =&gt; f({ ...props, extra }, ...args)
  }
  </code></pre>
  
  <p>I think it should be something like this, but I can't get it right:</p>
  
  <pre><code>/**
   * @param {(props: Props, ...args: Args) =&gt; Result} f
   * @param {Extra} extra
   * @template Extra
   * @template {{ extra: Extra }} Props
   * @template {Array} Args
   * @template Result
   * @returns {(props: Omit&lt;Props, 'extra'&gt;, ...args: Args) =&gt; Result}
   */
  </code></pre>
  
  <p>I have <code>Omit</code> defined as <code>type Omit&lt;T, K extends keyof T&gt; = Pick&lt;T, Exclude&lt;keyof T, K&gt;&gt;</code></p>
  
  <p>If this can not be done in a JsDoc, but can be done in a <code>.d.ts</code> file that is fine too.</p>
  
  <hr>
  
  <p><em>update</em></p>
  
  <p>A version that works from the outside:</p>
  
  <pre><code>/**
   * @template {Object} P
   * @template {Array} A
   * @template R
   * @param {(props: P, ...args: A) =&gt; R} f
   * @param {P['extra']} extra
   * @returns {(props: Omit&lt;P, 'extra'&gt;, ...args: A) =&gt; R}
   */
  export function provideExtra(f, extra) {
    return (props, ...args) =&gt; f(Object.assign({}, props, { extra }), ...args)
  }
  </code></pre>
  
  <p>This however produces an error for <code>Object.assign</code>: </p>
  
  <blockquote>
    <p>Argument of type <code>Pick&lt;P, Exclude&lt;keyof P, "extra"&gt;&gt; &amp; { extra: P["extra"]; }</code> is not assignable to parameter of type 'P'. [2345]</p>
  </blockquote>
  
  <p>In my naive mind it that type would result in <code>P</code>; leaving out <code>extra</code> and intersecting it with something that has <code>extra</code> with the correct type.</p>