【问题标题】:Async function missing a return statement?异步函数缺少返回语句?
【发布时间】:2018-04-29 03:26:24
【问题描述】:

我刚刚为我正在处理的错误编写了以下方法,并且想知道为什么编译器没有抱怨以下函数可能不返回?如果我改为写if (false),编译器会立即抱怨并非所有路径都返回值。

如果if (data && data.json().length) 为假怎么办?这个函数有返回任何东西吗?

private async getData(items: any[]): Promise<number> {
    for(const item of items) {
        let data = await item.promise;
        if (data && data.json().length) {
            return data.json().findIndex(d => d.fqdn);
        }
    }
}

谢谢

【问题讨论】:

    标签: typescript async-await


    【解决方案1】:

    Section 6.3 of the TypeScript spec 对此进行了解释(强调):

    返回类型不是 Void 类型、Any 类型或包含 Void 或 Any 类型作为组成部分的联合类型的显式类型函数必须在其主体中的某处至少有一个 return 语句强>。此规则的一个例外是函数实现包含单个“throw”语句。

    你的函数有一个可达的返回语句,所以它满足这个要求。如果将return 放在if (false) 中,则不会考虑它,因为它无法访问。

    如果它在没有显式返回的情况下终止,它将隐式返回undefined 的承诺,当strictNullChecks 选项未启用时,这是Promise&lt;number&gt; 的允许值。

    这与async 无关。以下也编译没有错误:

    function getData(): number { 
        if (1 + 1 === 3) {
            return 7;
        }
    }
    

    这样:

    function getData(): number { 
        if (1 + 1 === 3) {
            return undefined;
        }
    }
    

    如果 (data && data.json().length) 为假怎么办?这个函数有返回值吗?

    它返回一个解析为undefined的promise,因为它被标记为async,而async函数总是返回promise。

    请注意(正如 Tom Fenech 在我之前指出的那样),使用 strictNullChecks 会导致您的函数和此答案中的函数产生编译器错误,因为 undefined 不被认为是 number 的可能值时该选项已启用。

    【讨论】:

      【解决方案2】:

      async 函数总是返回一个承诺。如果if (false) TypeScript 编译器报错,因为return 语句无法访问。在这种情况下,该函数返回undefined 的承诺。如果data &amp;&amp; data.json().length 为假,也会发生这种情况,但编译器无法检测到此问题。

      如果函数没有返回默认值,则函数不需要在函数末尾显式return,但应相应键入:

      private async getData(items: any[]): Promise<number|void> {
          for(const item of items) {
              let data = await item.promise;
              if (data && data.json().length) {
                  return data.json().findIndex(d => d.fqdn);
              }
          }
      }
      

      【讨论】:

      • TypeScript 不关心函数是否返回 undefined 的承诺(除非启用了 strictNullChecks,在 OP 的情况下它们不是)。它关心函数是否至少有一个(可达的)return 语句,该语句返回可以强制转换为numberPromise&lt;number&gt; 的类型。您可以通过将 OP 示例中的 return 语句替换为 return undefined 来观察这一点。
      • 我相信在任何最近的 TS 答案中都应该假设 strictNullChecks,但这并不重要。我更新了答案以明确 function 返回未定义的承诺 不是 return statement is unreachable 的结果。 TypeScript 不关心这一点,但用户关心。关键是 Promise 对于可能返回未定义承诺的函数来说不是正确的类型。
      【解决方案3】:

      该函数总是返回一个 Promise。在函数隐式返回的情况下,Promise 将解析为 undefined。

      启用strictNullChecks 后,这会导致编译器错误。

      您可以在TypeScript playground 中看到这一点(尝试在选项中切换strictNullChecks):

      async function a(i: boolean): Promise<number> {
          if (i) return 5;
      }
      

      您也可以删除async 关键字并将返回类型更改为number,您将看到相同的行为。

      【讨论】:

      • 我很确定这与函数总是返回一个承诺无关,但strictNullChecks 确实会导致它出现编译器错误。
      • 我并不是说这是async 关键字特有的行为,我只是使用了与问题中相同的类型。我已经进行了编辑以使其明确。
      • 好的,但在 OP 的示例中,函数体实际上正在返回(据编译器所知)any。它无法确定data.json().findIndex(d =&gt; d.fqdn) 是什么类型。
      猜你喜欢
      • 1970-01-01
      • 2013-11-30
      • 2017-01-26
      • 2017-09-21
      • 2021-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-21
      相关资源
      最近更新 更多