title: TypeScript Type-safe Omit Function
body: <p>I want to replicate lodash's <code>_.omit</code> function in plain typescript. <code>omit</code> should return an object with certain properties removed specified via parameters after the object parameter which comes first.</p>
  
  <p>Here is my best attempt:</p>
  
  <pre><code>function omit&lt;T extends object, K extends keyof T&gt;(obj: T, ...keys: K[]): {[k in Exclude&lt;keyof T, K&gt;]: T[k]} {
      let ret: any = {};
      let key: keyof T;
      for (key in obj) {
          if (!(keys.includes(key))) {
              ret[key] = obj[key];
          }
      }
      return ret;
  }
  </code></pre>
  
  <p>Which gives me this error:</p>
  
  <pre><code>Argument of type 'keyof T' is not assignable to parameter of type 'K'.
    Type 'string | number | symbol' is not assignable to type 'K'.
      Type 'string' is not assignable to type 'K'.ts(2345)
  let key: keyof T
  </code></pre>
  
  <p>My interpretation of the error is that:</p>
  
  <ol>
  <li><p>Since key is a <code>keyof T</code> and <code>T</code> is an object, key can be a <code>symbol</code>, <code>number</code> or <code>string</code>.</p></li>
  <li><p>Since I use the <code>for in</code> loop, key can only be a <code>string</code> but <code>includes</code> might take a <code>number</code> if I pass in an array, for example? I think. So that means there's a type error here?</p></li>
  </ol>
  
  <p>Any insights as to why this doesn't work and how to make it work are appreciated!</p>