Typescript通用数组被强制转换为any []?

时间:2019-05-28 21:25:51

标签: typescript

我正在尝试编写一些通用数组实用程序函数,但是当我尝试从另一个函数调用时,编译器似乎将通用类型转换为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添加到很多东西中,并且可以成功编译,但是似乎编译器应该自己解决这个问题。

1 个答案:

答案 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];
    }
}

也许您的实际代码更复杂,如果将其发布(也许在另一个问题中),我们可以看到是否可以找到比不安全类型声明更好的解决方案。