为什么 TS+Axios 提示不能将类型 "void" 分配给类型 "{}"?

题目描述

最近在学习TS+Vue3,自己找了一个Vue2项目想改写成Vue3,但是在封装axios的时候遇到问题了
image.png

相关代码

  • serve/axios.ts文件

    import axios from 'axios';
    import { getStorage } from '@/utils/storage'
    const TIMEOUT: number = 18000
    
    // axios.defaults.retryDelay = 1000;
    // axios.defaults.retry = 4; 
    axios.defaults.baseURL = "http://127.0.0.1:8360/admin";
    axios.defaults.timeout = TIMEOUT;
    // 请求拦截器
    axios.interceptors.request.use((config) => {
      // console.log(config.headers);
      const token = getStorage('token');
      // console.log(token);
      if (token) {
          config.headers['X-Hioshop-Token'] = token;
      }
    
      // config.headers.common['X-Hioshop-Token'] = token;
      return config
    }, (error) => {
      return Promise.reject(error)
    });
    
    // 响应拦截器
    axios.interceptors.response.use((response) => {
      // console.log(response);
    
      if (response.data?.errno === 0) {
          return response.data.data;
      }
    
      else {
          return response
      }
    
    }, (error) => {
      console.log(error);
    
      return Promise.reject(error)
    });
    
    
    
    export default axios;
    
  • serve/index.ts
    存放请求方法

    import axios from './axios';
    
    export async function post(url: string, params?: object) {
      const res = await axios({
          url: url,
          data: params,
          method: "post"
      }).catch(error => {
          console.log(error);
      })
    
      // console.log(res);
      return res;
    }
    
    export async function get(url: string, params?: object | string) {
      const res = await axios({
          url: url,
          params: params,
          method: 'get'
      }).catch(error => {
          console.log(error);
      })
      return res;
    }
  • api.ts

    import { get } from '@/server';
    
    export function getWelCome(data?: object) {
      return get('index', data);
    }
  • 组件中使用

    const getInfo =  () => {
    // console.log(getWelCome());
    getWelCome().then(res=>{
      console.log(res);
      allData.value = res;
    })
    };

你期待的结果是什么?实际看到的错误信息又是什么?

还是个菜鸟,还太会传说中的类型体操,希望大佬可以通俗一点儿

阅读 5.6k
2 个回答

根据代码推断类型(可在代码上按 F12 跳过去看):

  • getWelcome 的返回类型和 get 的返回类型一致
  • get 返回的是 await axios() 的类型

    • axios() 返回的是 AxiosPromise<T = any> 类型,这个类型定义成 Promise<AxiosResponse<T>>
    • await 会解 Promise,所以 await axios() 的类型是 AxiosResponse<T>

由上述推断,getWelcome() 返回的是一个 Promise<AxiosResponse<T>> 由于 T 没指定,所以使用默认值 any,即 Promise<AxiosResponse<any>>。调用其 then() 方法,参数会解 Promise,所以参数 res 的类型是 AxiosResponse<any>

我没看到代码中有 allData 的定义,但估计是直接封了个默认对象:allData = ref({}),由于没有指定类型,所以 allData.value 就是一个空对象类型 {},从 AxiosResponse<any> 不能赋值过去。

这里有两个问题:

  1. allData应该指定类型 allData = ref<any>({}),如果能准确的知道其类型的数据结构(类型)那就使用具体的类型
  2. axios 调用返回的是响应对象,也就是 AxiosResponse,这个对象中含 HTTP 状态信息,头信息等很多信息,如果你想直接取结果,应该是取它的 .data

附:AxiosReponse 的定义(F12 跟代码应该查得到的)

export interface AxiosResponse<T = any, D = any>  {
  data: T;
  status: number;
  statusText: string;
  headers: AxiosResponseHeaders;
  config: AxiosRequestConfig<D>;
  request?: any;
}
getWelCome().then((res:any)=>{
  console.log(res);
  allData.value = res;
})

最简单方法,给接口返回值加个any,或者你知道服务端返回值格式给加个类型

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Microsoft
子站问答
访问
宣传栏