Richard Howell-Peak
Richard Howell-Peak

Reputation: 487

Typescript Generic Class Constructor Argument with static methods

So the basic problem I have is this.

I have a base class from which all other classes are derived. It has a static method. Something like this:

class BaseClass {
  static blah() : string {
    return 'base';
  }
}

class OtherClass extends BaseClass {
  static blah() : string {
    return 'other';
  }
}

class DoesntExtend extends SomeOtherClass {

}

Then I have a function which I want to pass in the Class Constructor and call the static method, but I'm having trouble with the method signature.

I want to use it something like this:

console.log(funcCaller(BaseClass)) -> outputs 'base'
console.log(funcCaller(OtherClass)) -> outputs 'other'
console.log(funcCaller(DoesntExtend)) -> won't compile, since DoesntExtend won't have the static method

So I thought to do something like:

type Constructor<T extends BaseClass > = new(...args: any[]) => T;

function funcCaller<T extends BaseClass>(c : Constructor<T>) : string {
  return c.blah();
}

but tsc complains that

Property 'blah' does not exist on type 'Constructor'

any ideas?

Upvotes: 1

Views: 833

Answers (1)

Nishant
Nishant

Reputation: 55856

The funcCaller function needs to accept typeof the class to access the static properties. This is because static properties exist on the type while the signature you have used accepts an instance of that type. As the docs says, "To refer to the type that the value f has, we use typeof".

TS Playground

class BaseClass {
  static blah() : string {
    return 'base';
  }
}

class OtherClass extends BaseClass {
  static blah() : string {
    return 'other';
  }
}

class DoesntOverride extends BaseClass{

}

class SomeOtherClass {
}

class DoesntExtend extends SomeOtherClass {

}

function funcCaller(c : typeof BaseClass) : string {
    return c.blah();
}

// base
console.log(funcCaller(BaseClass));

// other
console.log(funcCaller(OtherClass));

// base
console.log(funcCaller(DoesntOverride));

// Shows error
console.log(funcCaller(DoesntExtend));

Upvotes: 1

Related Questions