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

作者站长头像
站长
· 阅读数 18

题目描述

最近在学习TS+Vue3,自己找了一个Vue2项目想改写成Vue3,但是在封装axios的时候遇到问题了为什么 TS+Axios 提示不能将类型 "void" 分配给类型 "{}"?

相关代码

  • 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;
    })
    };

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

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

回复
1个回答
avatar
test
2024-07-12

根据代码推断类型(可在代码上按 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;
}
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容