Search code examples
typescriptgenericstypescript-genericstype-constraints

Typescript generic type constraint from array of types


I have an array of types declared as

const APIS = [NewsApi, CommentsApi, FileApi];

I want to have a method that accepts one of these types from that APIS array, like the following:

myMethod<T extends anyof APIS>(apiType: T): T {
    const api = new apiType(); //pseudo code, does not work off course
    // some common configuration code
    return api;
} 

. I cannot do myMethod<T extends NewsApi|CommentsApi>(): T, as the APIS array is auto generated. Is this possible with typescript?

Update:

Aleksey's solution works great for passing in the input. However, the return type cannot be inferred from the usage.

const myApi = myMethod(NewsApi);

In above case, myApi is not of type NewsApi, but NewsApi|CommentsApi|FileApi. Is it possible to set the return type explicitly to instance of input api type?


Solution

  • If you can change definition of the array to readonly tuple:

    const APIS = [NewsApi, CommentsApi, FileApi] as const;
    

    then you can get union of possible array values using lookup type:

    type ApiConstructors = typeof APIS[number];
    
    function myMethod<T extends InstanceType<ApiConstructors>>(apiType: new () => T): T {
      return new apiType();
    }
    
    const api = myMethod(NewsApi); // api is of type NewsApi
    

    InstanceType utility used to get instance type of a constructor function.

    Playground