typescriptgenericsoverloading

typescript class overloading


Is it possible to overload whole class with a type definition?

For example, there are two classes that are different only in that if one of them has a generic typedef, it should also accept it in constructor parameter. If not, there is no need for that param and custom constructor.

export abstract class MyClass implements OtherClass {
  readonly foo;

  static get bar(): string {
    return "bar";
  }
}

export abstract class MyPayloadClass<T> extends MyClass {
  constructor(public readonly payload: T) {
    super();
  }
}

The goal is to merge these two together. So we only have a MyClass and it optionally has a constructor with payload only if the type <T> is provided.


Solution

  • While you can't have a single implementation for both classes, you can have a single constructor for both, and in effect have a unitary way of creating either the generic or non generic version.

    What we do, is declare a variable that will hold the payload version of the class constructor and overload the constructor with the non payload version. The runtime implementation will always be the payload version, but you get type checking for the non payload version if there is no payload.

    export abstract class MyClass  {
      readonly foo;
    
      static get bar(): string {
        return "bar";
      }
    }
    
    export abstract class MyPayloadClass<T> extends MyClass {
      constructor(public readonly payload: T) {
        super();
      }
    }
    
    
    
    const Both: typeof MyPayloadClass & { new() : MyClass } = MyPayloadClass as any;
    
    let a = new Both();
    let b = new Both(1);
    
    b.payload // ok
    a.payload // error
    
    Both.bar // statics work