1

I would like to create function with optional count of type parameters. For example, function accepts parameters, where each parameter is array and returns array, where nth item is random item from nth parameter:

const getRandomItems<T1, T2, T3>(...arrays: [T1[], T2[], T3[]]): [T1, T2, T3] = {
    const result = []

    for (const items of arrays) {
        result.push(items[Math.floor(Math.random() * items.length)])
    }

    return result
}

const fruits = ['Apple', 'Orange', 'Banana']
const colors = ['Red', 'Green', 'Blue']
const cars = [new Car('Ferrari'), new Car('Porsche')]

// E.g. ['Apple', 'Blue', new Car('Porsche')]
getRandomItems<string, string, Car>(friuts, colors, cars)

// E.g. ['Orange', new Car('Ferrari'), 'Red']
getRandomItems<string, Car, string>(friuts, cars, colors)

This function accepts 3 parameters and returns array with 3 parameters. But can I create function, that:

  • Accept any number of typed parameters, e. g. <T1, T2, T3, T4>,
  • Accept same number of parameters as type parameters: ...arrays: [T1[], T2[], T3[], T4[]],
  • Returns array with same types as typed parameters: [T1, T2, T3, T4]?
// Something like this:
const getRandomItems<...T>(...arrays: [...T[]]): [...T] = {

}
0

1 Answer 1

1

You'll want to use a mapped type to loop over the type of the input and convert each array type into the type of its elements:

type UnwrapArray<T> = T extends (infer U)[] ? U : T;

type Result<T extends any[][]> = {
  [I in keyof T]: UnwrapArray<T[I]>;
}

function getRandomItems<T extends any[][]>(...arrays: T): Result<T> {
    const result = []

    for (const items of arrays) {
        result.push(items[Math.floor(Math.random() * items.length)])
    }

    return result as any;
}

First of all, we need a helper type UnwrapArray to extract the type of the elements from an array. See this SO answer for more information.

Next, we have the type for the return value of the function. It takes type T which is a doubly nested array, iterates over all the keys [I in keyof T] (since this is an array, the keys are the index) and extracts the element type of each array UnwrapArray<T[I]>.

Finally the function only takes one generic argument T with the same constraint as in Result. This way it doesn't matter how many arguments are provided.

Note: it is necessary to cast the result to any inside the function body as the compiler doesn't have a high enough understanding of what Result<T> actually is.

Playground

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.