【问题标题】:Correctly Typing Return Value of Async Fetch Functions正确键入异步获取函数的返回值
【发布时间】:2019-07-23 10:17:34
【问题描述】:

Javascript 中的异步函数流程需要在 Typescript 中键入这样的工作流作为多个可能的返回值。我的主要问题是这是否必要和最佳实践。

如果一切顺利,该函数将返回我想要的值。如果它不顺利,我可能想抛出一个错误。

但是如果我抛出一个错误,那并不会传达函数的返回值,所以我仍然需要通知 typescript 函数应该返回什么值。

所以我们开始编写看起来有点像这个例子的代码:

class PostsClient {

   public async fetchPosts(): Promise<Posts[]> {
     try {
        const posts: Posts[] = await this.httpClient.fetch(this.apiUrl);
        return posts;
     } catch (e) {
        this.logger.captureError(e);
        throw e;
     }
   }

}

// Error from Typescript: `Function lacks ending return statement and return type does not include 'undefined'.`

为了响应来自 Typescript 的警告,我们将函数的返回值更改Promise&lt;Posts[] | undefined&gt;

我希望在另一个调用者(例如布局控制器)中使用此函数可以与打字稿引擎进行通信,该函数不会返回所需类型 Posts[] 的唯一原因是如果抛出错误, 并且函数的控制流无论如何都会被中断。

但最终会遇到这样的问题。

class PostLayoutController {

    public async fetchAndStorePosts(): void {
       const posts = await this.postsClient.fetchPosts();
        this.sendAnalyticsData(posts)  // ERROR -- posts could be undefined!
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    }
}

通过简单地使用 return 语句来防止进一步的逻辑执行来处理这个问题是否正确?

if (!posts) {
   return;
}

或者有更好的解决方案吗?

【问题讨论】:

  • posts 不会在那里未定义 - 如果 fetchPosts 抛出错误,则永远无法调用 sendAnalyticsData。错误类型隐式为any;参见例如stackoverflow.com/a/41079355/3001761.

标签: typescript asynchronous return-value


【解决方案1】:

正如@jonrsharpe 在对我的问题的评论中提到的那样,Typescript 实际上确实认识到 fetchPosts 函数会引发错误。

我的问题是,在实际实现中,我们使用了 handleApiErrors 函数,该函数没有可识别的 Typescript 的“错误抛出”签名,因此它假设执行流程将继续。

这是如何实现实际代码的示例:

class PostLayoutController {

    public async fetchAndStorePosts(): void {
       try {
          const posts = await this.postsClient.fetchPosts();
          this.storePosts(posts);
       } catch (e) {
          this.handleApiErrors(e);
       }
    }


    private handleApiErrors(e: Error) {
       if (e.code === 400) {
          throw new InvalidSubmissionError(e.message, ...more props)
       }

       // Some other error class cases.

       throw e;
    }
}

所以我看到我需要在 catch 块中执行错误逻辑,而不是将其委托给另一个函数,以便 Typescript 了解正在发生的事情。

【讨论】:

    猜你喜欢
    • 2018-04-09
    • 2021-03-31
    • 1970-01-01
    • 2021-04-12
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    相关资源
    最近更新 更多