title: Using typescript Exclude with generic type
body: <p>A routine update of dependences in my TypeScript-based Nodejs project has caused me to receive TypeScript compilation errors in a generic class used to manage <a href="https://mongoosejs.com/" rel="nofollow noreferrer">mongoose</a> models. I've narrowed the problem down to what seems to be an issue with TypeScript handling of generic types.</p>
  <p>I've constructed the following minimal example:</p>
  <pre><code>interface I {
      p: string;
  }
  
  class Foo&lt;T extends I&gt; {
      exclude: Exclude&lt;'p', 'q'&gt; = 'p'; // OK
      excludeI: Exclude&lt;keyof I, 'q'&gt; = 'p'; // OK
      excludeT: Exclude&lt;keyof T, 'q'&gt; = 'p'; // TS2322: Type '&quot;p&quot;' is not assignable to type 'Exclude&lt;keyof T, &quot;q&quot;&gt;'.
  }
  </code></pre>
  <p>Note that the only difference between the types of <code>excludeI</code> (which compiles fine) and <code>excludeT</code> (which fails to compile with the given error) is that the latter uses the generic type <code>T</code> rather than the interface type <code>I</code>.</p>
  <p>As <code>T</code> is specified to extend <code>I</code>, I would expect these two lines to be treated identically. Indeed, it seems that the <code>keyof</code> operator has no problem working with them interchangeably:</p>
  <pre><code>class Foo&lt;T extends I&gt; {
      keyof: 'p' = 'p'; // OK
      keyofI: keyof I = 'p'; // OK
      keyofT: keyof T = 'p'; // OK
  }
  </code></pre>
  <p>I have used <a href="https://www.typescriptlang.org/play?ts=4.0.5#code/JYOwLgpgTgZghgYwgAgJLIN4Chm%20QBwC5kBnMKUAcwG4sBfLLUSWRFAKUxzwEdiyKIGvUYIANnBIlkAMQD2cgDwAVZBAAekEABNpqAHxc8yANYQAnnJjEA5PhvIAvMjs3qyAPQfkAeQDS3LhmljCoxMFWaE4u9u5evgHGETDK4RaRqs6ucd7%20jMbxYAAWwNKlyMUoAK4kKAiSKJTAAG5UBFByAEZiEAC2ZSDIALJyQgq1gWrq4lXaEMQAotNisxCKrgA0pukwyOyGWbGeuYl4GjNzYchLF2vJaFv3%209HZxwmT5ytzqdfLq4r3ZSPHZ7A4xNxvZQAZQATABmGEw4jKcz4FA2ABE%20AxDnKIDkYGQkhIwEoIDg3RQYDkFVR6JuXzuIKByAxPAx%20hsADpJpN4jU2hotLoidI0VBkMBevger0IOA4GBgKNkJEGatCB9NPLdLZ7FNhdInsgAPzIEAQZrQZBpELITLgnLvYxCnUkK73dCunRGkGcM0Wq0S20ZF5HeJ5F3an0-QEGt3bO3%2082W60h3YO17xaHwxHIukuLE4yXSfGE4mk8mUio0sAFmxx70itkY00poM2xMZbkiZBAA" rel="nofollow noreferrer">this example on the TypeScript Playground</a> to experiment with different TS versions, and it doesn't seem to be version-dependent behavior.</p>
  <p>Can anyone shed some light on what's going on with <a href="https://www.typescriptlang.org/docs/handbook/utility-types.html#excludetype-excludedunion" rel="nofollow noreferrer">Exclude&lt;&gt;</a> here?</p>