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.