我正在尝试编写一些通用数组实用程序函数,但是当我尝试从另一个函数调用时,编译器似乎将通用类型转换为any[]
并给了我这个错误:
Type 'any[]' is not assignable to type 'T'.
我的代码:
type UnwrapArray<T extends any[]> = T extends (infer G)[] ? G : never;
function removeFromArray<T extends any[]>(
array: T,
value: UnwrapArray<T>
) {
return array.filter(other => other !== value);
}
function toggleArrayValue<T extends any[]>(array: T, value: UnwrapArray<T>): T {
if(array.includes(value)) {
return removeFromArray<T>(array, value);
} else {
return [...array, value];
}
}
给我带来麻烦的具体几行是
return removeFromArray<T>(array, value);
还有
return [...array, value];
我发现我可以将as T
添加到很多东西中,并且可以成功编译,但是似乎编译器应该自己解决这个问题。
答案 0 :(得分:2)
您假设T
扩展any[]
意味着T
是一个数组,任何新数组都可分配给T
。这不是真的。
请考虑以下内容:
const myArr = Object.assign([1, 2, 3], {
extraProp : 1
})
toggleArrayValue(myArr, 1).extraProp // ts says this should be here where is my extraProp
extends any[]
是T
的下限,但可以是任何继承数组的东西(或元组,但这是蠕虫的另一种解释,为什么它不起作用)< / p>
至少从示例代码中不能确定为什么需要T
作为数组。您可以在没有此条件的情况下表达自己的意图:
function removeFromArray<T>(
array: T[],
value: T
) {
return array.filter(other => other !== value);
}
function toggleArrayValue<T>(array: T[], value: T): T[] {
if (array.includes(value)) {
return removeFromArray<T>(array, value);
} else {
return [...array, value];
}
}
也许您的实际代码更复杂,如果将其发布(也许在另一个问题中),我们可以看到是否可以找到比不安全类型声明更好的解决方案。