【问题标题】:Flow(InferError): Cannot call await with 'axios.get(...)' bound to 'p'Flow(InferError):无法调用 await 与 'axios.get(...)' 绑定到 'p'
【发布时间】:2019-07-01 18:35:43
【问题描述】:

我在使用 axios 时遇到了一些 Flow 错误。

Cannot call await with 'axios.get(...)' bound to 'p' because:
Either property 'error_message' is missing in 'AxiosXHR'. 
Or property 'data' is missing in 'Promise'

这是我的代码,尝试了类型注释。 (同样的错误没有AxiosPromise<Object> 注释。)错误在axios.get(url)。

  async handleAddressChange(): AxiosPromise<Object> {
    const url = `https://maps.googleapis.com/maps/api/place/autocomplete/json?key=${GoogleMapsApiKey}&input=${this.state.address}`;
    try {
      const { data, error_message } = await axios.get(url);
      if (error_message) throw Error(error_message);
      this.setState({
        addressPredictions: data.predictions,
        showPredictions: true
      });
    } catch (err) {
      console.warn(err);
    }
  }

有趣的是,在另一个文件中 axios 没有给出 Flow 问题:

export async function loginWithApi(creds: AuthParams) {
  const res = await axios.get(ApiUrls.login, { params: creds });
  return res.data;
}

我的文件中有import type { AxiosPromise, $AxiosXHR } from "axios";。

有人知道如何解决这个问题吗?

【问题讨论】:

    标签: axios flowtype


    【解决方案1】:

    如果出现错误,returned payload 中将没有 error_message,但错误会进入 catch 块。

    另外,handleAddressChange 不返回 AxiosPromise,而是返回隐含的 promise,正如它用 async 定义的那样

    所以,是这样的:

    async handleAddressChange(): Promise<void> {
    const url = `https://maps.googleapis.com/maps/api/place/autocomplete/json?key=${GoogleMapsApiKey}&input=${this.state.address}`;
        try {
          const { data } = await axios.get(url);
          this.setState({
            addressPredictions: data.predictions,
            showPredictions: true
          });
        } catch (err: AxiosError) {
          new Error(err);
        }
      }
    

    可能对你有用。注意AxiosError 定义。

    还有一点需要注意的是,您可以将返回的有效负载添加到 AxiosPromise 泛型中,即:

    type TExpectedLoginResponse = {
        ok: boolean,
        token: string
    }
    
    export async function loginWithApi(creds: AuthParams): AxiosPromise<TExpectedLoginResponse> {
      const res = await axios.get(ApiUrls.login, { params: creds });
      return res.data; // so now flow knows that res.data is type of TExpectedLoginResponse
    }
    

    希望对你有帮助。

    【讨论】:

    • 第一个建议基本上是好的,除了谷歌地图API返回error_message,例如,请求成功但搜索为空;所以我认为它不会引发错误。我为解决此问题所做的工作是:const { data, ...res } = await axios.get(url); if (res.error_message) throw Error(res.error_message); Flow 似乎可以使用其余参数,所以我可以从那里获得error_message。
    • @JonathanTuzman 这对我来说看起来很奇怪 - 如果 error_message 是响应正文的一部分,那么它应该在 data 中,不是吗?
    猜你喜欢
    • 2020-05-09
    • 2019-10-12
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 2019-01-08
    相关资源
    最近更新 更多