I have some generated code (gRPC) that produces various classes each of which have a static constructor function like static create(): Foo
. Each of these classes has its own static constructor function that explicitly returns itself (A's function returns an A
object, etc).
I'm trying to create a generic interface that captures this information, at compile time, and then write a generic function to refer to each class, and then pass a handler callback which receives an instance of that class.
// ----- generated code starts -----
class A {
name = 'AAA';
static create(): A {
return new A();
}
}
class B {
age = 32;
static create(): B {
return new B();
}
}
class C {
location = 'New York';
static create(): C {
return new C();
}
}
// ----- generated code ends -----
/**
* Represents a class that can be constructed by calling a static method
*/
interface StaticallyConstructable<OBJ> {
create(): OBJ;
}
function registerHandler<CLS extends StaticallyConstructable<CLS>>(ObjClass: CLS, handler: (obj: CLS) => void) {
const obj = ObjClass.create();
handler(obj);
}
registerHandler(C, (obj: C) => {
obj.location
});
The registerHandler
function itself compiles fine, but when I call it with an actual class like C
and a handler that receives a C
, I get the following error:
Property 'location' is missing in type 'StaticallyConstructable<C>' but required in type 'C'.
Edit: TS playground link
CodePudding user response:
CLS
should represent the instance type, so the ObjClass
should be of type StaticallyConstructable<CLS>
function registerHandler<CLS>(ObjClass: StaticallyConstructable<CLS>, handler: (obj: CLS) => void) {
const obj = ObjClass.create();
handler(obj);
}
registerHandler(C, (obj: C) => {
obj.location
});