【问题标题】:Type function return using contextual type rather than from inference类型函数返回使用上下文类型而不是推理
【发布时间】:2017-05-03 07:49:42
【问题描述】:

使用 Typescript 2.2.2(使用 strictNullChecks 选项为真)我对以下内容感到惊讶。这是错误还是预期行为?

interface Fn {
    (value: any): number;
}

var example1: Fn = function(value) {
    if (value === -1) {
        return undefined;  // no error, was expecting error
    }
    return value;
};

var example2 = function(value: any): number {
    if (value === -1) {
        return undefined;  // errors correctly
    }
    return value;
};

我知道example1 没有出错,因为函数返回类型被推断为any | undefined。然后将any | undefinedFn 返回类型的上下文类型进行比较,即number,因此发现是兼容的。相反,我希望函数的返回类型由上下文类型设置,而不是与之比较。有没有办法强制让Fn 的消费者也明确键入函数返回?

我想这又回到了只提供必须履行的合同的接口,而不是规定包括返回类型在内的实现。

另外(出于兴趣)当参数类型(number)导致推断的返回类型(number | undefined)与上下文类型(来自Fn2,即number)不兼容时,错误显然会被捕获):

interface Fn2 {
    (value: number): number;
}

// `example3` errors as function return type is inferred to be `number | undefined` which is incompatible with the expected `number` return type.
var example3: Fn2 = function(value) {
    if (value === -1) {
        return undefined;
    }
    return value;
};

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您分配给example1 的函数表达式的确切推断类型是(value: any) => any,因为返回类型any | undefined 已“折叠”为any。这种类型与Fn 兼容,因此被接受。

    我想这又回到了只提供必须履行的合同的接口,而不是规定包括返回类型在内的实现。

    这不是真的。相反,类型一致性非常严格——毕竟这就是 TypeScript 的目的 :)——当然,除了 any 涉及到时,它是语言中最宽松的类型。

    上下文类型不会将变量上声明的类型应用于函数表达式。相反,return 语句的类型有助于确定函数表达式的类型。出于这个原因,我认为如果没有对example1 的表达式进行显式类型注释,就无法在您展示的片段中实现类型安全。

    请注意example1example3之间的区别在于any是特殊的并且包含undefined,导致第一段中描述的“折叠”行为。

    【讨论】:

      【解决方案2】:

      对此的一种解决方案是将any 替换为所有可用的原语和非原语:

      interface Fn {
          (value: number | string | boolean | null | undefined | object): number;
      }
      
      // `example1` now errors as expected due to having a return type which is incompatible:
      //     Type 'string | number | boolean | object | null | undefined' is not assignable to type 'number'.
      //         Type 'undefined' is not assignable to type 'number'.
      var example1: Fn = function(value) {
          if (value === -1) {
              return undefined;
          }
          return value;
      };
      

      For an excellent explanation of why this works please see FstTesla's answer.

      【讨论】:

        猜你喜欢
        • 2016-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-21
        相关资源
        最近更新 更多