title: How to create a decorator that accepts an abstract class in Typescript
body: <p>I have a class decorator that adds a few properties to the class passed in.</p>
  <pre class="lang-ts prettyprint-override"><code>type Class&lt;T, TArgs extends any[] = any[]&gt; = (...args: TArgs) =&gt; T;
  
  export function myDecorator&lt;T extends Class&lt;any&gt;&gt;(Target: T) {
    const MyDecoratedClass = class extends Target {
      prop: string;
      fn(arg: string) {
        console.log(this.prop);
      }
    };
  
    const name = `Decorated${Target.name}`;
    Object.defineProperty(MyDecoratedClass, 'name', { value: name });
  
    return MyDecoratedClass as typeof MyDecoratedClass &amp; T;
  }
  
  class MyClass extends myDecorator(SomeClass)&lt;string&gt; {
    foo: string;
    // ...
  }
  
  class MyImplementedClass extends myDecorator(SomeAbstractClass)&lt;string&gt; {
    foo: string;
    // ...
  }
  </code></pre>
  <p>It works fine for non-abstract classes, but attempting to use it on abstract classes results in the error:</p>
  <blockquote>
  <pre class="lang-none prettyprint-override"><code>Cannot assign an abstract constructor type to a non-abstract constructor type. ts(2345)
  </code></pre>
  </blockquote>
  <p>This error message leads me to believe there <em>must</em> be a way to specify a type that accepts an abstract constructor type, otherwise it would (or should have) read something equivalent to <code>Types cannot bind to abstract constructors.</code></p>
  <p>I have a <code>Class</code> type:</p>
  <pre class="lang-ts prettyprint-override"><code>type Class&lt;T, TArgs extends any[] = any[]&gt; = new(...args: TArgs) =&gt; T;
  </code></pre>
  <p>I thought <em>maybe</em> I could use the <code>abstract</code> keyword to achieve my goal:</p>
  <pre class="lang-ts prettyprint-override"><code>type AbstractClass&lt;T, TArgs extends any[] = any[]&gt; = abstract new(...args: TArgs) =&gt; T;
  
  // or
  
  interface AbstractClass&lt;T, TArgs extends any[] = any[]&gt; {
    abstract new(...args: TArgs): T;
  }
  </code></pre>
  <p>but no dice.  The first results in a syntax error.  The second results in</p>
  <blockquote>
  <pre class="lang-none prettyprint-override"><code>'abstract' modifier cannot appear on a type member. ts(1070)
  </code></pre>
  </blockquote>
  <hr />
  <h3>Update</h3>
  <p>I found a case-specific workaround.  This decorator is used specifically for React components.  Therefore, I can create a base class, and extend that in my abstract class:</p>
  <pre class="lang-ts prettyprint-override"><code>class DecoratedClass&lt;P = {}, S = {}, SS = {}&gt; extends myDecorator(Component)&lt;P, S, SS&gt; { }
  
  abstract class MyClass extends DecoratedClass {
    // ...
  }
  </code></pre>