title: TypeScript Generics problem: type T (extends Type) is not assignable to T
body: <p>I have a problem with TypeScript generics in Deno.</p>
  <pre><code>abstract class Packet {
      public abstract read(): Uint8Array;
      public abstract write(data: Uint8Array): void;
  }
  
  type PacketData = Packet | Uint8Array;
  type HookCallbackResult&lt;T extends PacketData&gt; = T | null | undefined;
  type HookCallback&lt;T extends PacketData&gt; = (data: T) =&gt; HookCallbackResult&lt;T&gt;;
  
  interface HookCallbackInfo&lt;T extends PacketData&gt; {
      packetType: typeof Packet | &quot;any&quot;;
      callback: HookCallback&lt;T&gt;;
  }
  
  let callbacks: HookCallbackInfo&lt;PacketData&gt;[] = [];
  
  function hook&lt;T extends PacketData&gt;(packetType: typeof Packet | &quot;any&quot;, callback: HookCallback&lt;T&gt;) {
      callbacks.push({ packetType, callback });
      //                           ^^^^^^^^
      // error: TS2322 [ERROR]: Type 'HookCallback&lt;T&gt;' is not assignable to type 'HookCallback&lt;PacketData&gt;'.
      // Types of parameters 'data' and 'data' are incompatible.
      //     Type 'PacketData' is not assignable to type 'T'.
      //     'PacketData' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'PacketData'.
      //         Type 'Packet' is not assignable to type 'T'.
      //         'Packet' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'PacketData'.
  }
  </code></pre>
  <p>My purpose is to force a callback which is passed as 2nd argument to <code>hook</code> function to return a result of the same type as its argument OR <code>null</code> OR <code>undefined</code> and this type should be <code>Uint8Array</code> or already parsed <code>Packet</code> (or its child class) and nothing else. And <code>hook</code> function should store this hook callback for further use. Deno's version of TypeScript compiler panics on adding a callback to an object (declared with interface <code>HookCallbackInfo</code>) array.</p>
  <p>I guess I made a mistake somewhere with generics cause I don't understand properly how they work in TypeScript with these multiple type definitions (like <code>Type1 | Type2 | Type3</code>). Could you pls explain me what exactly I did wrong and how to do what I want in the proper way?</p>