title: Overloading class generics in typescript
body: <p>I am running against the following problem that I cannot seem to solve (I simplified the classes for this post). I eventually want to specify a variety of requests. These have a certain hierarchy which I plan to model using inheritance. As a starting point, I created an abstract base class:</p>
  
  <pre><code>export abstract class RequestBase&lt;TResult&gt; {
      public async execute(): Promise&lt;TResult&gt; {
          const response = await this.transmit();
          return this.getResult(response);
      }
  
      private async transmit(): Promise&lt;any&gt; {
          // Code that transmits the requests, and yields a response, typed "any".
      }
  
      protected abstract getResult(response: any): TResult;
  }
  </code></pre>
  
  <p><code>getResult</code> will be transforming the response object to a type defined by the deriving class. I plan to have more abstract classes on top of this, e.g:</p>
  
  <pre><code>export abstract class RequestDerived&lt;TResult&gt; extends RequestBase&lt;TResult&gt; {
      constructor() {
          super(); // some parameterization suited for this request type.
      }
  }
  </code></pre>
  
  <p>The problem I am running into, is that I am not always interested in the result of requests. This would mean that <code>TResult</code> is <code>void</code>. Ideally I would be able to write down something like this:</p>
  
  <pre><code>// A request that will convert the response to a number.
  export class FirstRequest extends RequestDerived&lt;number&gt; {}
  
  // A request for which we do not care about the result.
  export class SecondRequest extends RequestDerived {}
  </code></pre>
  
  <p>This notation is possible when I specify the generic constaint on <code>RequestDerived</code> as <code>&lt;TResult = void&gt;</code>, but this would still force me to implement <code>getResult</code> in <code>SecondRequest</code> which would just be a dummy function.</p>
  
  <p>What conceptually want to achieve, is to have a <code>getResult</code> implementation for <code>TResult = void</code>, and have the derived classes specificy it when <code>TResult != void</code>. Something like:</p>
  
  <pre><code>export abstract class RequestDerived&lt;TResult&gt; extends 
      RequestBase&lt;TResult&gt; {
      constructor() {
          super();
      }
  }
  
  // Note: No longer abstract - we know the implementation for TResult = void.
  // Not allowed: [ts] Duplicate identifier 'RequestDerived'. [2300]
  export class RequestDerived extends RequestDerived&lt;void&gt; {
      constructor() {
          super();
      }
  
      protected getResult(response: any): void {
          return; // We don't care about the result!
      }
  }
  </code></pre>
  
  <p>Is there some way to achieve this without having to define two differently names classes? The reason why I want to try to avoid this, because this carries over to the derived classes (all classes down the hierarchy would have two version too).</p>
  
  <p>Thanks in advance!</p>