I'd like to create an interface or a type that has static properties and a constructor signature. I'd like to use the interface/type for a parameter to a function. I've tried using an interface, but I can't declare static fields on an interface. I've also tried using an abstract class resembling the following:
interface IClassType {
instanceMethod: (param: string) => void;
}
abstract class IBaseClass {
static requiredProperty: string;
static optionalProperty?: boolean;
abstract new (param: number): IClassType;
}
I then tried to use the abstract class as a type in a function resembling the following:
// @param UserClass: must implement or extend IBaseClass
const demoFunction = (UserClass: IBaseClass) => {
const demoClass = new UserClass(3);
// Throws a compiler error:
// "Type 'IBaseClass' has no construct signatures."
const demoProp = UserClass.requiredProperty;
// Throws a compiler error:
// "Property 'requiredProperty' does not exist on type 'IBaseClass'.
// Did you mean to access the static member
// 'IBaseClass.requiredProperty' instead?"
}
Any assistance would be appreciated.
In your example, the type named IBaseClass
corresponds to an instance of the abstract IBaseClass
class. The type corresponding to the IBaseClass
class constructor would be typeof IBaseClass
, but you wouldn't want to use that type either because it's abstract and you wouldn't be allowed to construct it.
Instead you can declare an interface corresponding to the type of constructor you do want to pass in:
interface IClassTypeConstructor {
requiredProperty: string;
optionalProperty?: boolean;
new(param: number): IClassType;
}
So an IClassTypeConstructor
has the static properties you care about, as well as a construct signature that produces instances of IClassType
.
Now if you pass an object of that type to demoFunction()
, things should work as expected:
const demoFunction = (UserClass: IClassTypeConstructor) => {
const demoClass = new UserClass(3); // okay
demoClass.instanceMethod("abc"); // okay
const demoProp = UserClass.requiredProperty; // okay
}