Search code examples
typescripttypescript-typingsfactory-patternfactory-method

Class as instance vs Class definition | Typescript


By default, typescript rightfully infers a class type as an instance of said class rather than the class definition itself. I recently came across this distinction when refactoring a class factory method.

My question is what is the best way to indicate that an argument or type is an instance of the class or the callable definition of the class?

Take for example this class

class MyClass implements IMyClass {
  foo = 'foo';
  bar() {
    return 'bar';
  }
}

Now I have two functions, the first callBar is expecting an instance of the class

function callBar(instance: MyClass) {
  return instance.bar();
}

The second classFactory is expecting the class definition.

function classFactory(MyClassDefinition: MyClass) {
  return new MyClassDefinition();
}

The problem is that this second function throws a type error

(parameter) MyClassDefinition: MyClass
This expression is not constructable.
  Type 'MyClass' has no construct signatures.(2351)

The solution I resorted to was to use the Class type from utility-types npm package. which is defined as...

type Class<T> = new (...args: any[]) => T;

function classFactory(MyClassDefinition: Class<MyClass>) {
  return new MyClassDefinition();
}

Is there a clearer, better or easier way of making this distinction?

Thanks!


Solution

  • You need to indicate it as a constructor type:

    function classFactory(MyClassDefinition: new () => MyClass) {
      return new MyClassDefinition();
    }