title: Enforce 'typeof BaseClass' when base class is generic
body: <p>Let's say I have a generic abstract base class and a set of classes that extend the base and provide the generic param.</p>
  <pre><code>abstract class BaseClass&lt;T&gt; {
    constructor(protected container: T[]) { }
    static someStaticFunc(): string {
      return 'I\'m the BaseClass';
    }
    getElement(i: number): T {
      return this.container[i]
    }
  }
  
  class ConcreteClass1 extends BaseClass&lt;number&gt; {
    static someStaticFunc(): string {
      return 'I\'m ConcreteClass1'
    }
  
    addNumber(element: number) {
      this.container.push(element);
    }
  }
  
  class ConcreteClass2 extends BaseClass&lt;string&gt; {
    static someStaticFunc(): string {
      return 'I\'m ConcreteClass2'
    }
  
    addStringTwice(element: string) {
      this.container.push(element);
      this.container.push(element);
    }
  }
  
  class ConcreteClass3 extends BaseClass&lt;boolean&gt; {
      // Doesn't add anything
  }
  </code></pre>
  <p>I define an interface structure where each value must be a <code>typeof BaseClass</code></p>
  <pre><code>interface SetOfBaseClasses {
    Class1: typeof BaseClass,
    Class2: typeof BaseClass,
    Class3: typeof BaseClass
  };
  </code></pre>
  <p>I want to create an object of that interface type, and assign the concrete classes to it. And then call each of the static functions on the class and get the expected results at the bottom.</p>
  <pre><code>const classes: SetOfBaseClasses = {
    Class1: ConcreteClass1,
    Class2: ConcreteClass2,
    Class3: ConcreteClass3
  }
  
  console.log(classes.Class1.someStaticFunc());
  console.log(classes.Class2.someStaticFunc());
  console.log(classes.Class3.someStaticFunc());
  
  // Expected output:
  // I'm ConcreteClass1
  // I'm ConcreteClass2
  // I'm the BaseClass
  </code></pre>
  <p>However, TypeScript does not see <code>ConcreteClass1</code>, <code>ConcreteClass2</code> or <code>ConcreteClass3</code> as compatible with <code>typeof BaseClass</code>. I figure this is because of the generic involved with BaseClass. So I also tried:</p>
  <pre><code>interface SetOfBaseClasses {
    Class1: typeof BaseClass&lt;unknown&gt;,
    Class2: typeof BaseClass&lt;unknown&gt;,
    Class3: typeof BaseClass&lt;unknown&gt;
  };
  </code></pre>
  <p>and even more precisely:</p>
  <pre><code>interface SetOfBaseClasses {
    Class1: typeof BaseClass&lt;number&gt;,
    Class2: typeof BaseClass&lt;string&gt;,
    Class3: typeof BaseClass&lt;boolean&gt;
  };
  </code></pre>
  <p>In either case, TypeScript does not seem to allow a generic parameter after <code>typeof Class</code></p>
  <p>I get two errors for each line in the interface that are something like this:</p>
  <pre><code>Call signature, which lacks return-type annotation, implicitly has an 'any' return type.(7020)
  Type parameter name cannot be 'number'.(2368)
  </code></pre>
  <p>Is there anyway to do this type of thing with TypeScript? Everything seems to be fine  with this approach until you involve generics.</p>
  <p><a href="https://www.typescriptlang.org/play?#code/IYIwzgLgTsDGEAJYBthjAgQmgpgYVXQB4AVAPgQG8AoBJAewDtIoBXeeqACgAcp6IOeDgAmDRhGABLRjigAuBCQDaAXQCUVBAF9aCSMAhTY%20%20gFscAZUlHYAMVaNYXdYpYyA5lT10oOCKxQjAgA5ACSADohZggQABY4WLgEaGAhANx6unQe-gCiyDgWElxSioysZiByrkredL7%20gcHxUmAAdLBMkjJyylKqWdS61CipCHhMsH6CKegAjAg4AB6CjCIY2GD4hGBEFVVyFDR0BramFtaGxg5OLm7QnvUNM82hkdETUzM7qfMhQz0wBEIgAcpVqtwcIVihByhCas86K0Ol0JNJZFB2jxWGA4lxoUUcBJ1Jk6LoRmN0F8nD85mAAExLVbEjZJbb0ojuRgeY56M7GC5WGw3RzOWrcrwnF5NILvKIxSa0-y-dAMgHk6hAkHWKCeEgAd2MOAJMOJcP0jx5mmlyLibU63QxcmxuPxhNhpJ8sXtqKdvSxOLxpqJJLJOmGWqpGCV0xV9IAzMy1mytqq9iB6PRCsBGHyGggAPSFhAAEXoODAjBCiGBYlzAE9WjzI9QZIIoAAzOCJSz%20ADynbT9Mrz3p80UEAbPBw9E77PT%20wRUDIABo9PSGZPp7P58Pdlyrbz13RE9uZ3OF5zM9mcLmyMNMtRO2KjEwEGYMS5nmjIEhdpWih9hAg77qko4ALxIhMuwTjScazLBJ4NJuiixnSuwMshp67AmaHfPGuGAnQv63u0yD0B4XDRpW7Tju0YDmMK1z2GKLheiRTCMYU5GUdRAEdJuDFMVcti3OKHHiNxOC8VRNGCbhwmXCKrF3OoXp6MWCB5MsM7CGI9CsBAOJwppJZhJ86GEX8ZkIBZioEYhqQMrZ9k%20okYHoMMQA" rel="nofollow noreferrer">Typescript Playground</a></p>