How to associate a type with a generic function under the hood

97 views Asked by At

I have a class (eg "Collection") that knows what type it is working with (eg "DBType") and that class gets in the constructor a generic function (eg "Transform") that gets the subtype of DBType and returns an instance of another class based on this subtype. When the user calls collection's method with some parameters, collection can determine which subtype of DBType will be redirected to the transform function.

If I pass the subtype DBType to the transfrom separately, it works fine, but I'm stuck in the class. I can't seem to find a solution how should I do this. Maybe this is a limitation of typescript.

I made a simple example in the playgroud that should be enough. Thanks for the help.

1

There are 1 answers

2
Tadhg McDonald-Jensen On

The root of the problem is that you are using ReturnType<typeof transform> and the transform function is both generic and has overloads. ReturnType can't cope with either of these things which is why you are getting incorrect results. The correct logic you are looking for is along the lines of:

type TranslateDoc<T> = T extends TSomeDoc ? SomeDoc<T>
                     : T extends TOtherDoc ? OtherDoc<T>
                     : T

// TEST TRANSFORM
function transform<T extends TSomeDoc | TOtherDoc | Partial<TCountDoc>>(doc: T): TranslateDoc<T> {

I don't think there is a way to get the TCollection to be generic as to what transform it is using, for this transform you can write the class like this:

// second generic isn't used, relies specifically on the transform function only.
declare class TCollection<Doc, Fn extends typeof transform = typeof transform> {
    constructor(transform: Fn);

    findOne<T extends Partial<Doc>>(doc: T): TranslateDoc<T>;
}

As far as I know there is no way to use something like higher order generics (passing the TranslateDoc generic to the class in a way that it's argument is specified by the class)