The argument labeled as 'readonly...' cannot be assigned to a parameter labeled as '...[]' in this context

There's a question that resembles mine but addresses a different issue, which can be seen 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)
    }
  }

An error occurs when using getRandomItem() within the code.

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)

My goal with the code (for better understanding):

  1. Create an array with specific literal values
  2. Define a type declaration (a union of literals) from that array (TypeScript: Define a union type from an array of strings)
  3. Use that type as an annotation on a class attribute
  4. Select a random element from the array to assign to the location attribute

I need the array to be immutable for a loop in another part of the code.

Some "solutions" I came across:

  1. Removing as const from apparelLocation solved the issue, but it allows assigning any value to location, not just the specified ones
  2. Removing type annotation from the function and using array: any also resolved the problem, but it gives a warning

I apologize if the mistake seems obvious, as I am relatively new to TypeScript.

Answer №1

It seems that TypeScript is highlighting an issue with passing an immutable array to a function where the parameter array is mutable. The solution is to declare the function parameter as readonly:

function getRandomItem<T>(array: readonly T[]): T {
   // ...
}

By making the parameter readonly, TypeScript will no longer raise any complaints as the array cannot be modified within the function.

Alternatively, you can modify the call like this:

this.location = getRandomItem([...apparelLocation])

In this way, you are passing a copy of the original array instead of the immutable one, which aligns with the mutable function parameter.

Answer №2

To avoid using a generic type, you can include a readonly type similar to my example below:

createRoutes(navigation.options.routes)

const createRoutes = (localRoutes: readonly NavigationRecordRaw[]) => {
  // your code here
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having difficulty updating the value of a FieldArray with setFieldValue in Formik

Thank you for taking the time to read this. I am currently working on creating a form using Formik that involves nesting a FieldArray within another FieldArray. Oddly enough, setFieldValue seems to be functioning correctly as I can log the correct values ...

The functionality of lazy loading and routing in Angular 10 appears to be malfunctioning

I recently attempted to implement routing and lazy loading in Angular 10.1.6, but for some unknown reason, I've encountered issues where the routing and lazy loading of a module simply isn't functioning as expected. Despite referring to the offic ...

Observable map encounters an error when attempting to retrieve essential data from the backend server

Here is my approach: getDropdownData(id: number | 195731): Observable<ClinicTrialSettingProp> { return this.http .get<ClinicTrialSettingProp>(this.commonPatientURL + id + '/clinic-trials') .pipe(map(response => res ...

Exploring the Issue with SWR Hook in Next.js using TypeScript

Seeking assistance with the SWR hook as I navigate through some challenges while attempting to use it effectively. This time, the issue appears to be minor. The objective is to set a breakpoint in my API to retrieve data, using axios. The problem arises ...

What are the reasons for discouraging the use of canActivate always returning false?

I've searched extensively to avoid duplicate postings and tried various solutions, but unfortunately, none of them have resolved the issue. My implementation of canActivate to secure a dashboard seems to be working properly, but it's always retu ...

Navigating an array using ngFor and encountering an error message saying, "Identifier not specified"

While using ngFor to iterate through an array, I encountered the following error message: "Identifier 'expenseitem' is not defined. The component declaration, template variable declarations, and element references do not contain such a memb ...

Hold off until the observable has finished

map((tasks): any => { return tasks.map(task => ({ ...task, status: this.getStatus(task.owner, task.delegationState, task.assignee, task.id), })); }); I utilize the getStatus method within the map() operator from rxjs. getStatus( ow ...

Tips on Showing a Unique List in Mat-Table?

Here's what I'm trying to accomplish: I have a list and I want to display it without any duplicates. I attempted using the code (this.model.map(x => x.map), but it resulted in an error. Can anyone help me fix this? model: myModel[]; myObj:any; ...

Utilizing Fullcalendar 5 in conjunction with Angular: Embedding Components within Events

Recently, my team made the transition from AngularJS to Angular 12. With this change, I upgraded Fullcalendar from version 3 to version 5 and started using the Angular implementation of Fullcalendar: https://fullcalendar.io/docs/angular While navigating t ...

Retrieving data with .getJSON and iterating over an array

I'm currently attempting to iterate through a multidimensional array, but I'm encountering difficulties. $.getJSON("file.json", function(json) { for(var i = 0; i < json.length; i++) { var county = json.data[i][9]; c ...

Issue with IN operator functionality in TypeORM when used with MongoDB

My goal is to fetch a list of items using an array of IDs by utilizing the following code: import { In } from 'typeorm'; ...findBy({ _id: In(ids) }) The IDs are predefined upon creation: @Entity() export class Foo { @ObjectIdColumn({ generated ...

What is the appropriate directory to place the `typescript` package in order for WebStorm to recognize it?

According to the information on this webpage: The Configure TypeScript Compiler dialog box provides two options: Detect: WebStorm will look for a typescript package within the current project. If it finds one, it will use that package. Otherwise ...

Type inference error in TypeScript occurs within a conditional statement when the condition relies on the output of a function call rather than a boolean expression

In my TypeScript code, I have a Linked List class that is working perfectly. The class includes a Node type and functions to add items to the list. type ListItem = number | string | object; class Node { private value: ListItem; private next: Node | nu ...

Passing parameters in React classes is a crucial aspect of creating

Within a project I am currently working on, there is a const defined for the page header which takes in parameters and utilizes the information: interface UserProps { user?: { name: string, image: string }, loading?: boolean, error?: E ...

What is the best way to save an array in a session and retrieve it in Laravel?

There are certain fields in the form that need to be filled out. <form action="users/registration/new_user" method="post" class="new_user" enctype="multipart/form-data" novalidate="novalidate"> <div class="col-md-12 col-sm-12 col-xs-12 no-pa ...

Problem with sorting when using $in operator in MongoDB

I am looking to retrieve documents from a MongoDB collection where the IDs match those in an array: [ '5f80a44d0179262f7c2e6a42', '5f8c00762fae890e9c4d029c', '5f802cf8abac1116a46bf9d4' ] The problem arises when the docu ...

The initial function that gets executed in the lodash chain is tap()

When using lodash chain to perform actions synchronously, I encountered an issue where .tap() is executed before the desired stage. I have been unable to find a solution using promises. I expected lodash chain to ensure actions are carried out in a synch ...

Discovering the technique to unearth a specific value within an array nested within another array

I am encountering an issue with finding a value in one array inside another array and utilizing the resulting value to update the state using setState(). Here is the initial state: this.state = { initialStudents:[ {name:"str1",tags;["str","s ...

Java code producing incorrect output while attempting to retrieve the nth smallest element from an unsorted array

I'm attempting to find the nth minimum element from an unsorted array of integers. I have implemented the following solution: private static int nthMin(int[] array, int m) { int start = 0; int end = array.length - 1; int index = 0; in ...

What is the best way to access an external array using ng-repeat in AngularJS?

My dataset consists of 3 separate arrays. "areas": { "default": [ { "area": "Master Bedroom", "uuid": "986e3f42-1797-49ae-b060-181a33b9", "description": "", "new": [ { "value": "986e3f42-1797-49ae-b060-181a3 ...