Reputation: 274
There's a similar question but it's a different problem from mine found here Argument of type '...' is not assignable to parameter of type '...' 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)]
}
apparel.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)
}
}
Will give an error inside when using the 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)
What I'm trying to do (in case needed for a better understanding):
location
attributeAs to why I need the first reason is because I need do a loop somewhere else.
Few "fixes" I found:
as const
from the apparelLocation
made it work but I can assign any value to location and not just those 4array: any
also works but it's giving a warningApologies if it's an obvious mistake by me since I'm relatively new to typescript.
Upvotes: 20
Views: 33199
Reputation: 375
If you don't want to use generic type you can add readonly type like me:
generateNavigations(router.options.routes)
const generateNavigations = (localRoutes: readonly RouteRecordRaw[]) => {
// your staff
}
Upvotes: 1
Reputation: 1407
Unless someone proves me wrong, what I understood is that typescript is complaining that you're passing an immutable array to the function, because the function parameter array
is mutable and can be edited, while the value you're passing is a constant.
The better solution is to setup the function paramater as readonly:
function getRandomItem<T>(array: readonly T[]): T {
// ...
}
By setting the parameter as readonly, typescript won't complain anymore because you won't be able to modify it inside the function.
Another, less nice, solution could be editing the call like this:
this.location = getRandomItem([...apparelLocation])
This way, you're not passing the original, immutable array, but just a copy of it that can be handled and is coherent with the function parameter being mutable.
Upvotes: 22