“参数'__0'和'值'的类型不兼容”是一个错误吗?

时间:2018-11-13 15:38:22

标签: typescript

此类型签入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;
}

1 个答案:

答案 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)