Error specializing base class's static method in a subclass

Viewed 26

Here's a simplified example of what I'm doing:

enum Type {A, B}

class Base<T extends Type> {
  constructor(public type: T) {}

  static create<T extends Type>(type: T): Base<T> {
    return new Base(type);
  }
}

class A extends Base<Type.A> {
  static override create(): A {
    return super.create(Type.A);
  }
}

But I'm getting this error:

Class static side 'typeof A' incorrectly extends base class static side 'typeof Base'.
  The types returned by 'create(...)' are incompatible between these types.
    Type 'A' is not assignable to type 'Base<T>'.
      Type 'Type.A' is not assignable to type 'T'.
        'Type.A' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Type'. ts(2417)

Why is this? I don't understand how "'T' could be instantiated with a different subtype of constraint 'Type'" when I've explicitly extended from Base<Type.A>. How do I work around this to create specializations of my base class?

1 Answers

We have a few issues here:

  1. You use value, not type in the child class.

javascript class Base<T extends Type> means you have to provide T which extends Type. But you provide a value javascript class A extends Base<Type.A>

In Generics you can only provide type, not value/instance. Examples:

class Animal {}
class Cat extends Animal {}

class AnimalInfo<T extends Animal> {}

const catInfo = new AnimalInfo<Cat>(); //valid - we provide type

const catInstane = new Cat();
const anotherCatInfo = new AnimalInfo<catInstane>(); // not valid

A valid, although not very useful example would be:

enum Type {
  A,
  B,
}

enum AnotherType {
  C,
}

type CombinedEnum = Type & AnotherType;

class Base<T extends Type> {
  constructor(public type: T) {}

  static create<T extends Type>(type: T): Base<T> {
    return new Base(type);
  }
}

class A extends Base<CombinedEnum> {
}

  1. Static methods cannot be overridden. Only instance methods can be overridden

javascript static override create() ... is not a valid construction.

  1. super has no meaning in a static method. super applies to an instance, not a static class implementation.
  static method(): Something {
    return super.method();
  }

a valid construction would be:


class BaseClassType {
  static method(): Something {
   //...
  }
}

class AnotherClass {
  static method(): Something {
    return BaseClassType.method();
  }
}
Related