Home > Mobile >  Typescript error when passing const array to generic function
Typescript error when passing const array to generic function

Time:04-17

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);
                             ~~~~~~

CodePudding user response:

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];
}
  • Related