'Typescript error when passing const array to generic function
I'd like to be able to choose a random element from the SHAPES array, while also keeping it as const so that the Shape type can be used elsewhere in the code. Ideally, I want to be able to use the below randomChoice function for both const and non-const arrays.
const SHAPES = [
'circle',
'square',
'triangle',
] as const;
type Shape = typeof SHAPES[number];
console.log('Available shapes are:');
for (let shape of SHAPES) {
console.log(` ${shape}`);
}
function randomChoice<T>(arr: T[]): T {
let index = Math.floor(arr.length * Math.random());
return arr[index];
}
console.log('A random shape is:');
console.log(randomChoice(SHAPES));
When I run the above, I get this error:
C:\ts>npx tsc test.ts
test.ts:18:26 - error TS2345: Argument of type 'readonly ["circle", "square", "triangle"]' is not assignable to parameter of type 'any[]'.
The type 'readonly ["circle", "square", "triangle"]' is 'readonly' and cannot be assigned to the mutable type 'any[]'.
18 console.log(randomChoice(SHAPES));
~~~~~~
And if I change the last line to this:
let choice = randomChoice(SHAPES);
console.log(choice);
I get a slightly different error:
C:\ts>npx tsc test.ts
test.ts:18:27 - error TS2345: Argument of type 'readonly ["circle", "square", "triangle"]' is not assignable to parameter of type 'unknown[]'.
The type 'readonly ["circle", "square", "triangle"]' is 'readonly' and cannot be assigned to the mutable type 'unknown[]'.
18 let choice = randomChoice(SHAPES);
~~~~~~
Solution 1:[1]
Using as const on SHAPES declares it as a readonly array. Remove as const if you can, or change the function definition to accept Readonly<T[]> (sandbox):
function randomChoice<T>(arr: Readonly<T[]>): T {
let index = Math.floor(arr.length * Math.random());
return arr[index];
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ori Drori |
