此类型签入TypeScript Playground,但在v3.1.6上失败:
function head([a]) {
return a;
}
const x: number[] = [[1], [2]].map(head)
错误消息:
server/src/mock-resolvers/mock-data.ts(549,36): error TS2345: Argument of type '([a]: [any]) => any' is not assignable to parameter of type '(value: number[], index: number, array: number[][]) => any'.
Types of parameters '__0' and 'value' are incompatible.
Type 'number[]' is not assignable to type '[any]'.
Property '0' is missing in type 'number[]'.
这是一个错误吗?我不明白该错误消息或看不到代码出了什么问题。
更详细地说明类型并不能解决问题,如果函数定义如下,则会出现类似的错误:
function head([a, _b]: [number, number]): number {
return a;
}
答案 0 :(得分:2)
如果在操场上启用strictFunctionTypes
,则可以重现该错误。您可以阅读有关此选项here的更多信息,但要点在于它从函数中消除了双方差。
在您的情况下,数组[[1], [2]]
的类型不是Array<[number]>
,而是类型为Array<number[]>
,因为typescript不会为数组文字推导出元组类型,除非它指向这样做。这会导致错误,因为您的函数显式地接受了元组类型[any]
。数组类型不能分配给具有单个元素(甚至是any
的元组)的元组。
最简单的解决方案是显式指定数组的类型:
function head([a] : [number]) { // type is not required but it's best to not leave implict any
return a;
}
const data: Array<[number]> = [[1], [2]]
const x: number[] = data.map(head)
您可以创建一个辅助函数,该函数将从参数类型推断出元组:
function tuple<T extends any[]>(...a: T) {
return a;
}
const x: number[] = [tuple(1), tuple(2)].map(head)
或直接推断出一个元组数组:
function tupleArray<T extends [any]|any[]>(...a: T[]) {
return a;
}
const x: number[] = tupleArray([1], [2]).map(head)