“只读...”类型的参数不可分配给“...[]”类型的参数

Arn*_*ied 16 arrays typescript

有一个类似的问题,但与我在这里发现的问题不同,类型为“...”的参数不能分配给类型为“...”的参数 TS 2345

utils.ts(https://www.typescriptlang.org/docs/handbook/2/generics.html#generic-types

export function getRandomItem<T>(array: T[]): T {
  return array[Math.floor(Math.random() * array.length)]
}
Run Code Online (Sandbox Code Playgroud)

服装.ts

import { getRandomItem } from "@/assets/ts/utils"

export const apparelLocation = ["HEAD", "TORSO", "ARMS", "LEGS"] as const
export type TypeApparelLocation = typeof apparelLocation[number]

// ...

export class Apparel {
  / ...
  location: TypeApparelLocation

  constructor(rating: number) {
    // ...
    this.location = getRandomItem(apparelLocation)
    }
  }
Run Code Online (Sandbox Code Playgroud)

使用的时候会报错getRandomItem()

Argument of type 'readonly ["HEAD", "TORSO", "ARMS", "LEGS"]' is not assignable to parameter of type '("HEAD" | "TORSO" | "ARMS" | "LEGS")[]'. The type 'readonly ["HEAD", "TORSO", "ARMS", "LEGS"]' is 'readonly' and cannot be assigned to the mutable type '("HEAD" | "TORSO" | "ARMS" | "LEGS")[]'.ts(2345)

我正在尝试做什么(如果需要更好的理解):

  1. 创建一个包含带有文字值的数组的变量
  2. 从该数组创建类型声明(文字的联合)(TypeScript:从字符串数组定义联合类型
  3. 使用该类型作为类属性的注释
  4. 从数组中选择一个随机元素分配给location属性

至于为什么我需要第一个原因是因为我需要在其他地方进行循环。

我发现了一些“修复”:

  1. as const从 中删除apparelLocation使其工作,但我可以为位置分配任何值,而不仅仅是这 4 个
  2. 删除函数上的类型注释并使用普通array: any也可以,但它会发出警告

如果这是我的一个明显错误,我很抱歉,因为我对打字稿还比较陌生。

Dra*_*o96 16

除非有人证明我错了,否则我的理解是打字稿抱怨您将不可变数组传递给函数,因为函数参数array是可变的并且可以编辑,而您传递的值是常量。

更好的解决方案是将函数参数设置为只读:

function getRandomItem<T>(array: readonly T[]): T {
   // ...
}
Run Code Online (Sandbox Code Playgroud)

通过将参数设置为只读,打字稿将不再抱怨,因为您将无法在函数内修改它。

另一个不太好的解决方案可以像这样编辑调用:

this.location = getRandomItem([...apparelLocation])
Run Code Online (Sandbox Code Playgroud)

这样,您就不会传递原始的、不可变的数组,而只是传递它的一个可以处理的副本,并且与可变的函数参数保持一致。