Search code examples
typescripttypescript-generics

Pass an array of generics in a generic


Given the following:

type MyGeneric<S extends string> = {
  prop: S;
};

type MyType = {
  generics: MyGeneric[];
  // Generic type 'MyGeneric' requires 1 type argument(s). ts(2314)
};

I want MyType to have a list of those generics, which could all be different. E.g. MyGeneric<'hello'> and MyGeneric<'world'> could be objects inside the generics array of MyType. This is not possible in this scenario because TS expects a type argument in MyGeneric[].

If it was a single generic as a prop, I could just pass the parameter to MyType, like this:

type MyType<S extends string, Generic extends MyGeneric<S>> = {
  generic: Generic;
};

But in this case, it is an array. Also if all the generics in the array were the same, I could do this:

type MyType<S extends string, Generic extends MyGeneric<S>[]> = {
  generics: Generic;
};

But I want to make the array so they could be different.

Is it possible to have an array of multiple different generics, and if yes, how?

PS: If I made an English mistake or if any of this isn't clear, please ask me.


Solution

  • You could make MyType generic in an array/tuple of the type arguments, and have the generics property be a mapped type over that array/tuple type:

    type MyType<S extends string[]> = {
      generics: { [I in keyof S]: MyGeneric<S[I]>; }
    }
    

    Generic mapped types turn arrays into arrays and tuples into tuples. So MyType<[S1, S2, S3, S4]> is {generics: [MyGeneric<S1>, MyGeneric<S2>, MyGeneric<S3>, MyGeneric<S4>]}. Which means you can do this:

    const g: MyType<["x", "y", "z"]> = {
      generics: [{ prop: "x" }, { prop: "y" }, { prop: "z" }]
    }
    

    Playground link to code