5

I would like to pass type information for class, with hinting the compiler that the given parameter is not an instance of a class but the class definition. How can I do that?

import * as Routes from '../routes';
import * as Entities from '../entities';

export class RouteManager {
  public router = Router();
  private connection = getConnectionManager().get();

  constructor() {
    this.addRoute(Routes.VideoRoute, Entities.Video);
  }

  addRoute(routeClass: AbstractRoute<AbstractEntity>, entity: AbstractEntity): void {
    const instance = new routeClass(entity, this.connection.getRepository(entity))
    this.router.get(instance.route, instance.find);
  }
}

Here the compiler complains about the new routeClass(entity, this.connection.getRepository(entity)) line because it thinks routeClass is an instance of AbstractRoute<AbstractEntity> and not the exported class definition for it.

I have tried usingAbstractRoute<AbstractEntity>.constructor but Typescript doesn't seem to know this structure.

NoNameProvided
  • 8,608
  • 9
  • 40
  • 68

1 Answers1

11

The syntax for this looks a little bit weird. Basically you define a signature that uses something like new(...args: any[]) => T. You of course can be more strict by replacing T with your class and the args with the constructor signature.

I would recommend something like this:

class Foo {}
type Constructor<T> = new(...args: any[]) => T;

function createFoo(thing: Constructor<Foo>) { return new thing(); }
Sebastian Sebald
  • 16,130
  • 5
  • 62
  • 66
  • It throws the following: Type 'typeof Video' is not assignable to type 'Constructor – NoNameProvided Apr 25 '17 at 12:32
  • 1
    There is no `Video` type in your example, but from the looks of it you're using the same identifier multiple times. That's also what the error tells you: *Two different types with this name exist* PS: This seems to be an issue with your code. Can you copy/paste my example code into your code base + check if it works? – Sebastian Sebald Apr 25 '17 at 12:40
  • okay hear me out: what if I want to say that I can accept any class so long as it extends class `Bar`? – J-Cake Oct 16 '20 at 13:12
  • You mean polymorphism? – Sebastian Sebald Oct 16 '20 at 21:18