Home > Net >  How to generically refer to a type that has a static constructor function in Typescript
How to generically refer to a type that has a static constructor function in Typescript

Time:02-15

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
});

Playground Link

  • Related