我一直遇到这个问题(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[]'.
我知道我可以修改函数也采取readonly
数组:
export type AllowReadonly<T extends any[]> = T | readonly T[number][]
const doSomethingWithNumbers = <T extends <number[]>>(numbers: AllowReadonly<T>) => {}
但随后我在doSomethingWithNumbers
中遇到了完全相同的问题,因为numbers
参数现在也可以是readonly
。
解决这个问题的好方法是什么?
EDIT:
我在一个问题中发现了这个更好的答案,该问题旨在不仅从数组中删除readonly
修饰符,而且还从对象中删除。
这个方法对数组和对象都有效:
原始答:
我发现的一种方法是使用此函数在传递到函数时删除readonly
修饰符:
const removeReadonly = <T extends any>(arr: T[] | readonly T[]): T[] => arr as T[]
使用(运动场链接):
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;