The issue of inconvenience arises when dealing with `as const` arrays, as the readonly T[] is not directly assignable to T[]. The challenge lies in how to effectively remove

I encounter this issue repeatedly (playground link):

const arr = [1,2,3] as const

const doSomethingWithNumbers = <T extends number[]>(numbers: T) => {}

doSomethingWithNumbers(arr)
//                     ^
// Argument of type 'readonly [1, 2, 3]' is not assignable to parameter of type 'number[]'.
//  The type 'readonly [1, 2, 3]' is 'readonly' and cannot be assigned to the mutable type 'number[]'.

I understand that I can adjust the function to also accommodate readonly arrays:

export type AllowReadonly<T extends any[]> = T | readonly T[number][]

const doSomethingWithNumbers = <T extends <number[]>>(numbers: AllowReadonly<T>) => {}

However, this leads to the same issue within doSomethingWithNumbers, as the numbers parameter can now also be readonly.

What is a effective way to address this challenge?

Answer №1

Solution:

I stumbled upon this superior answer in a thread dedicated to removing the readonly modifier from not just arrays, but also objects.

This method caters to both arrays and objects: playground link


Initial solution:

Here's a neat little function that strips away the readonly modifier when inputting into the function:

const removeReadonly = <T extends any>(arr: T[] | readonly T[]): T[] => arr as T[]

Example usage (playground link):

const arr = [1,2,3] as const

const doSomethingWithNumbers = <T extends number[]>(numbers: T) => {}

const removeReadonly = <T extends any>(arr: T[] | (readonly T[])): T[] => arr as T[];

const nonReadonlyArr = removeReadonly(arr)  // (1 | 2 | 3)[];
doSomethingWithNumbers(nonReadonlyArr)      // No error;

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

Transforming a solitary JSON object into a JSON array using PHP

i am making a request to coincap.io for a single JSON object {"altCap":282255454377.94916,"bitnodesCount":11508,"btcCap":149160858393,"btcPrice":8830.18849156212,"dom":63.86,"totalCap":431416312770.94904,"volumeAlt":709387849.4057536,"volumeBtc":12537293 ...

Do I need to use [providers] when implementing constructor dependency injection?

Currently following a step-by-step guide on managing tasks and it includes the following code snippet: import {TodoDataService} from './todo-data.service'; @Component({ // ... providers: [TodoDataService] }) constructor(private todoDa ...

Error: The function $compile does not exist

Currently, I am working on developing an AngularJS directive using TypeScript. While testing my code in the browser, I encountered the following error: TypeError: $compile is not a function at compileComponent.js:14 Interestingly, the TypeScript compiler ...

Prohibit the Use of Indexable Types in TypeScript

I have been trying to locate a tslint rule in the tslint.yml file that can identify and flag any usage of Indexable Types (such as { [key: string] : string }) in favor of TypeScript Records (e.g. Record<string, string>). However, I haven't had a ...

Is it possible to extend the Object class in order to automatically initialize a property when it is being modified?

My experience with various programming languages leads me to believe that the answer is likely a resounding no, except for PHP which had some peculiar cases like $someArray['nonexistentKey']++. I'm interested in creating a sparse object whe ...

Is it necessary to include async/await in a method if there is already an await keyword where it is invoked?

Here are the two methods I have written in Typescript: async getCertURL(pol: string): Promise<string> { return await Api.getData(this.apiUrl + pol + this.certEndpoint, {timeout: 60000}).then( (response) => { return response.data.certUR ...

Tips for combing 2 JSON Arrays using Groovy

Looking to combine two JSON arrays into one using Groovy scripting. def branchTags = new JsonBuilder() branchTags branches, { String branch -> tag branch type 'b' } println(branchTags.toString()) //produces [{ ...

Having trouble retrieving form values in Typescript React, only receiving HTML tag as output

I am having an issue with retrieving the form value to my useRef hook as it returns the HTML tag of the form instead. To solve this, I attempted to specify the type HTMLFormElement inside the chevrons and set null as the initial value for my useRef hook. ...

The sum is being treated as a concatenation instead of an addition in this case

Why is the somma value showing the concatenation of totaleEnergetico and totaleStrutturale instead of a sum? RiepilogoCombinatoStComponent.ts export class RiepilogoCombinatoStComponent implements OnInit { constructor() { } interventi: AssociazioneI ...

Error: The specified updateTag type in the Angular SEO service is not compatible

I am in the process of developing an SEO service using Angular's Meta service (https://angular.io/api/platform-browser/Meta) Within the service, there is a method for managing social media tags that seems to be encountering issues and producing the f ...

What is the simplest way to transform a JSON containing strings into a JSON with arrays?

I am tasked with creating a method named public string PrepareForDeserialization(string json) that will transform a JSON string such as: {"To":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a2ccc3cfc7e2c1cdcfd2c3ccdb8cc1cdcf" ...

Typescript encounters difficulty locating the Express module

My venture into creating my debut NodeJS application has hit a roadblock. Following advice from multiple blogs, I have been attempting to build my first nodejs app in typescript by following the steps below: npm install -g express-generator npm install - ...

Issue with rest operator behavior in TypeScript when targeting es2018

This specific code snippet functions properly in the TypeScript Playground... class Foo { constructor(...args: any[]) { } static make(...args: any[]): Foo { return new Foo(...args); } } Example However, when trying to incorpora ...

Assign the image source to the file path located in the data directory

Is there a way to dynamically set the src attribute of an <img> tag in an HTML file using a string path from a file? The path is retrieved from the cordova.file.dataDirectory Cordova plugin within Ionic2 (TypeScript) and it typically looks like this ...

Inserting an array into a MySQL database using PHP

I'm currently facing an issue when it comes to inserting values from this array. Here is an example: $arr = json_decode($_POST['dynfields'], true); //{"dynfields":{"dynfields[0][DescRepair]":"Desc repair","dynfields[0][NestParts]":"Part ...

Angular 4 incorporates ES2017 features such as string.prototype.padStart to enhance functionality

I am currently working with Angular 4 and developing a string pipe to add zeros for padding. However, both Angular and VS Code are displaying errors stating that the prototype "padStart" does not exist. What steps can I take to enable this support in m ...

What is the best way to verify a field against a set of string values using Typescript in a NestJS application

I currently have an Enum containing various timezones listed below export enum Timezones { 'Europe/Andorra', 'Asia/Dubai', 'Asia/Kabul', 'America/Antigua' } In the DTO file, I am attempting to valid ...

What is the best way to determine the highest value?

How can I ensure that the data is displayed based on the condition c.date <= this.selectedReport.report_date? The current code snippet if (Math.max(...this.costs.map(c => c.date))){} seems to be causing an issue where no data is being displayed. What ...

Creating a randomly generated array within a Reactjs application

Every time a user clicks a button in reactjs, I want to create a random array of a specific size. The code for generating the array looks like this: const generateArray = (arraySize: number): number[] => { return [...Array(arraySize)].map(() => ~~( ...

Exported data in Vue3 components cannot be accessed inside the component itself

Essentially, I'm working on creating a dynamic array in Vue3. Each time a button is clicked, the length of the array should increase. Below is the code snippet. <div class="package-item" v-for="n in arraySize"></div> e ...