代码之家  ›  专栏  ›  技术社区  ›  Evan Carroll

您将如何称呼typescript不能做的这种推理?

  •  0
  • Evan Carroll  · 技术社区  · 5 年前

    如果将函数赋给 map 无法推断数组的类型。

    > let rfn1 = (a, fn:((x:number)=>number) ) => a.map(fn);
    
    > .type rfn1
    
    let rfn1: (a: any, fn: (x: number) => number) => any
    

    你可以看到那里 a 属于类型 any 即使它必须是类型 number[] 为类型的函数提供有效参数 ((x:number)=>number) .

    同样,您可以看到这个问题可以用显式类型来解决,

    > let rfn2 = (a: number[], fn:((x:number)=>number) ) => a.map(fn);
    
    > .type rfn2
    let rfn9: (a: number[], fn: (x: number) => number) => number[]
    

    如果需要显式键入,您会将当前缺少的推理类型称为什么?

    1 回复  |  直到 5 年前
        1
  •  1
  •   Fenton    5 年前

    我能看出你的思路…但这取决于许多无法证明的假设。所以我称之为 a 类型:

    由于无法证实的假设而扩大了类型

    如果你从内部工作,你有一个功能,就是 兼容的 具有的回调函数 array.map :

    (value: number, index: number, array: number[]) => {}
    

    我们必须假设我们知道的函数类型 ((x: number) => number) 只能用于 排列图 -这是第一个无法证明的假设。

    我们把视野扩大了一步 a.map(...) . 这个 能够 排列图 但也可能是 geoAwesome.map 或者任何其他我们创造了 map 方法。所以假设 a.map 排列图 是我们第二个无法证明的假设。

    即使将这两个假设结合起来,我们仍然无法证明 必须 做一个数组。

    class NotArray {
      map(fn: (num: number) => number) {
        return fn(3);
      }
    }
    
    let rfn1 = (a, fn: ((x: number) => number)) => a.map(fn);
    
    let res1 = rfn1([1, 2, 3], (x) => x);
    console.log(res1);
    
    let res2 = rfn1(new NotArray(), (x) => x);
    console.log(res2);
    

    看看这个人为的例子,你可以看到 几乎可以是任何类型(只要它具有兼容的 地图 方法。因此, any .

    只有当我们注释 参数编译程序能证明 不是其他类型的吗-现在我们的 res2 示例将生成一个错误。

    let rfn1 = (a: number[], fn: ((x: number) => number)) => a.map(fn);