将 const 数组传递给泛型函数时出现 Typescript 错误

Typescript error when passing const array to generic function

我希望能够从 SHAPES 数组中选择一个随机元素,同时将其保持为 const,以便可以在代码的其他地方使用 Shape 类型。理想情况下,我希望能够对 const 和非 const 数组使用下面的 randomChoice 函数。

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

当我 运行 以上时,我得到这个错误:

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

如果我将最后一行更改为:

let choice = randomChoice(SHAPES);
console.log(choice);

我得到一个稍微不同的错误:

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

SHAPES 上使用 as const 将其声明为 readonly 数组。如果可以,删除 as const,或更改函数定义以接受 Readonly<T[]> (sandbox):

function randomChoice<T>(arr: Readonly<T[]>): T {
  let index = Math.floor(arr.length * Math.random());
  return arr[index];
}