'Inconvenience when working `as const` arrays - readonly T[] not assignable to T[] - how to remove readonly modifier from array [duplicate]
I keep running into this problem all the time (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 know I can modify the function to also take readonly arrays:
export type AllowReadonly<T extends any[]> = T | readonly T[number][]
const doSomethingWithNumbers = <T extends <number[]>>(numbers: AllowReadonly<T>) => {}
but then I just run into the exact same problem inside doSomethingWithNumbers, since numbers parameter can now also be readonly.
What is a good way to tackle this issue?
Solution 1:[1]
EDIT:
I found this even better answer in a question that aims to remove readonly modifier not only from arrays, but also objects.
This is the approach that works for both arrays and objects: playground link
Original answer:
One way I found is using this function to remove the readonly modifier when passing into the function:
const removeReadonly = <T extends any>(arr: T[] | readonly T[]): T[] => arr as T[]
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;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
