Function to pick N random items from array in Typescript

Tags: , ,



This is the code. Got the idea from this answer.

Typescript playground

I’m using the generic type parameter: T extends unknown[], since this function should work for any kind of array.

export const pickRandomItems = <T extends unknown[]> (arr: T, n: number): T => {
  const shuffled = Array.from(arr).sort(() => 0.5 - Math.random());
  return shuffled.slice(0, n);
};

But I’m getting the following error on the return statement:

enter image description here

enter image description here

It goes away if I do a type assertion. But why is that necessary? Am I doing something wrong?

enter image description here

NOTE:

The following line is evaluated as unknown[], so why is the type assertion necessary anyway?

const result = shuffled.slice(0, n);

Answer

Change the type parameter to be the array item, not the whole array:

export const pickRandomItems = <T extends unknown> (arr: T[], n: number): T[] => {
  const shuffled = Array.from(arr).sort(() => 0.5 - Math.random());
  return shuffled.slice(0, n);
};

Playground Link

While T extends unknown[] does mean T can be any array, it could also be a subtype of Array, which means slice will not return the appropriate type (it will return Array instead of whatever T is). Generally you can’t assign a concrete type to a generic type parameter, because the generic type parameter could be any sub type that is decided by the caller, while you are using a specific concrete type in your implementation.



Source: stackoverflow