This is the code. Got the idea from this answer.
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:
It goes away if I do a type assertion. But why is that necessary? Am I doing something wrong?
NOTE:
The following line is evaluated as unknown[], so why is the type assertion necessary anyway?
const result = shuffled.slice(0, n);
Advertisement
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);
};
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.


