title: TypeScript, generics and instanceof
body: <p>I have the following code:</p>
  <pre><code>abstract class BaseToken {}
  
  class OpenParen extends BaseToken {
      public static assert(t: BaseToken): OpenParen {
          if (t instanceof OpenParen) {
              return t;
          } else {
              throw typeAssertionError;
          }
      }
  }
  
  class CloseParen extends BaseToken {
      public static assert(t: BaseToken): CloseParen {
          if (t instanceof CloseParen) {
              return t;
          } else {
              throw typeAssertionError;
          }
      }
  }
  </code></pre>
  <p>The <code>assert</code> functions can be used to check whether a given instance of <code>BaseToken</code> is in fact a certain specialization of it.</p>
  <pre><code>const t: BaseToken = getTokenFromSomewhere();
  const oparen = OpenParen.assert(t); // type of oparen is OpenParen, exception if not
  </code></pre>
  <p>As there are many more classes other than <code>OpenParen</code> and <code>CloseParen</code> derived from <code>BaseToken</code>, this is obviously a lot of boilerplate. I'd like to move the implementation of <code>assert</code> into the base class. The following does not work:</p>
  <pre><code>abstract class BaseToken {
      public static assert&lt;T&gt;(t: BaseToken): T {
          if (t instanceof T) { // T used as a value here
              return t;
          } else {
              throw typeAssertionError;
          }
      }
  }
  
  class OpenParen extends BaseToken {}
  class CloseParen extends BaseToken {}
  </code></pre>
  <p>The problem is that on the one hand, this doesn't compile as <code>instanceof</code> requires a value, not a class, and on the other hand, this approach does not bind <code>T</code> to the subclass type, so <code>OpenParen.assert</code> would still be a generic.</p>
  <p>I believe that I could achieve this in C++ with the <em>Curiously recurring template pattern</em> (CRTP), but that doesn't work in TypeScript. Is there some other trick to do the same thing?</p>