Nathaniel Tucker
Nathaniel Tucker

Reputation: 597

How to constraint type of abstract class in Typescript

This is what I want to do:

abstract class AbBase
  static newDerived<T extends typeof AbBase>(this: T) {
    return class A extends this {
      //...
    }
  }

Essentially I want newDerived to only be called from non-abstract implementations.

However, I get this error on the extends this part: "Type 'T' is not a constructor function type. Did you mean for T to be constrained to type 'new (...args: any[]) => AbBase'?"

But then if I do

  static newDerived<T extends typeof AbBase>(this: new (...args: any[]) => AbstractInstanceType<T>) {

it says, "Base constructor return type 'AbstractInstanceType' is not an object type or intersection of object types with statically known members."

Upvotes: 1

Views: 1275

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250336

You can constrain T to be a constructor that returns AbBase. This will solve both the non-abstract class requirement and will satisfy the compiler that this can be inherited:

abstract class AbBase {
    static newDerived<T extends { new (...a: any[]) : Pick<AbBase, keyof AbBase> } >(this: T) {
        return class A extends this {

        }
    }
}

AbBase.newDerived() // error

class Derived extends AbBase {}
Derived.newDerived() // ok 

Upvotes: 1

Related Questions