【问题标题】:Axios post request with typescript issue带有打字稿问题的 Axios 发布请求
【发布时间】:2021-10-02 14:38:18
【问题描述】:

我正在尝试将打字稿添加到我当前的项目中,因此在将它与 Axios 发布请求一起使用后,我遇到了一个问题。

用例是我想在我的帖子请求中发送“电子邮件”“名字”“姓氏”和“密码”,作为回应我想要“accessToken”

下面是代码

export interface UserRegistrationModel {
  email: string;
  password: string;
  firstname: string;
  lastname: string;
}



export const register = async (user: UserRegistrationModel) => {
  const { data } = await http.post<UserRegistrationModel>("/users", user);
  return data;
};

这是我提交注册表后调用的函数

register(values)
        .then((data) => {
          console.log(data.accessToken);
          setLoading(false);

        })
        .catch(() => {
          setLoading(false);

        });

所以当我尝试通过 data.acessToken 访问“accessToken”时,在我的 then 块中抛出错误

“UserRegistrationModel”类型上不存在属性“accessToken”

所以我尝试定义一个名为“AuthModel”的新接口,但是当我将它分配给像这样的数据时

export interface AuthModel {
  accessToken: string
}


 register(values)
        .then((data:AuthModel) => {
          console.log(data.accessToken);
          setLoading(false);
        })
        .catch(() => {
          setLoading(false);
          setSubmitting(false);
          setStatus("Registration process has broken");
        });

它说

'(data: AuthModel) => void' 类型的参数不可分配给 '(value: UserRegistrationModel) => void | 类型的参数 许诺”。参数'data'和'value'的类型是 不相容。 “UserRegistrationModel”类型中缺少属性“accessToken”,但在“AuthModel”类型中是必需的。

下面是任何人都想看的 axios 配置

// http.ts

import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios";

enum StatusCode {
  Unauthorized = 401,
  Forbidden = 403,
  TooManyRequests = 429,
  InternalServerError = 500,
}

const headers: Readonly<Record<string, string | boolean>> = {
  Accept: "application/json",
  "Content-Type": "application/json; charset=utf-8",
  "Access-Control-Allow-Credentials": true,
  "X-Requested-With": "XMLHttpRequest",
};

// We can use the following function to inject the JWT token through an interceptor
// We get the `accessToken` from the localStorage that we set when we authenticate
const injectToken = (config: AxiosRequestConfig): AxiosRequestConfig => {
  try {
    const token = localStorage.getItem("accessToken");

    if (token != null) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  } catch (error: any) {
    throw new Error(error);
  }
};

class Http {
  private instance: AxiosInstance | null = null;

  private get http(): AxiosInstance {
    return this.instance != null ? this.instance : this.initHttp();
  }

  initHttp() {
    const http = axios.create({
      baseURL: "https://api.example.com",
      headers,
      withCredentials: true,
    });

    http.interceptors.request.use(injectToken, (error) =>
      Promise.reject(error)
    );

    http.interceptors.response.use(
      (response) => response,
      (error) => {
        const { response } = error;
        return this.handleError(response);
      }
    );

    this.instance = http;
    return http;
  }

  request<T = any, R = AxiosResponse<T>>(
    config: AxiosRequestConfig
  ): Promise<R> {
    return this.http.request(config);
  }

  get<T = any, R = AxiosResponse<T>>(
    url: string,
    config?: AxiosRequestConfig
  ): Promise<R> {
    return this.http.get<T, R>(url, config);
  }

  post<T = any, R = AxiosResponse<T>>(
    url: string,
    data?: T,
    config?: AxiosRequestConfig
  ): Promise<R> {
    return this.http.post<T, R>(url, data, config);
  }

  put<T = any, R = AxiosResponse<T>>(
    url: string,
    data?: T,
    config?: AxiosRequestConfig
  ): Promise<R> {
    return this.http.put<T, R>(url, data, config);
  }

  delete<T = any, R = AxiosResponse<T>>(
    url: string,
    config?: AxiosRequestConfig
  ): Promise<R> {
    return this.http.delete<T, R>(url, config);
  }

  // Handle global app errors
  // We can handle generic app errors depending on the status code
  private handleError(error: any) {
    const { status } = error;

    switch (status) {
      case StatusCode.InternalServerError: {
        // Handle InternalServerError
        break;
      }
      case StatusCode.Forbidden: {
        // Handle Forbidden
        break;
      }
      case StatusCode.Unauthorized: {
        // Handle Unauthorized
        break;
      }
      case StatusCode.TooManyRequests: {
        // Handle TooManyRequests
        break;
      }
    }

    return Promise.reject(error);
  }
}

export const http = new Http();

【问题讨论】:

    标签: reactjs typescript react-typescript


    【解决方案1】:

    可以设置不同的类型来输入输出数据(axios 定义):

    post<T = never, R = AxiosResponse<T>>(url: string, data?: T, config?: AxiosRequestConfig<T>): Promise<R>;
    

    所以,在你的情况下,它会是这样的:

    export interface UserRegistrationModel {
      email: string;
      password: string;
      firstname: string;
      lastname: string;
    }
    
    export const register = async (user: UserRegistrationModel) => {
      const { data } = await http.post<UserRegistrationModel, AxiosResponse<{ accessToken: string }>>("/users", user);
      return data;
    };
    

    【讨论】:

      【解决方案2】:

      将您的注册功能更改为:

      export const register = async (user: UserRegistrationModel) => {
        const { data } = await http.post<AuthModel>("/users", user);
        return data;
      };
      

      同样在你的类中,post 的类型应该是:

      post<T = any>(
          url: string,
          data?: T,
          config?: AxiosRequestConfig
        ): Promise<T> {
          return this.http.post(url, data, config);
      }
      

      “UserRegistrationModel”类型上不存在属性“accessToken”

      您将data 的返回类型设置为UserRegistrationModel,并且打字稿告诉您accessToken 在该类型上不存在。这从您的定义中应该是显而易见的。

      '(data: AuthModel) => void' 类型的参数不可分配给 '(value: UserRegistrationModel) => void | 类型的参数 许诺”。参数 'data' 和 'value' 的类型不兼容。 “UserRegistrationModel”类型中缺少属性“accessToken”,但 在“AuthModel”类型中是必需的。

      您正在尝试传递一个期望 AuthModel 作为唯一参数的函数,但您的 register 函数将再次将 UserRegistrationModel 传递给该函数。 Typescript 只是通知您这一点。

      【讨论】:

      • 试过它说“'UserRegistrationModel'类型的参数不能分配给'AuthModel'类型的参数。'UserRegistrationModel'类型中缺少属性'accessToken'但在'AuthModel'类型中是必需的。”
      • @Ratnabhkumarrai 查看更新后的答案。您需要更改post的类型
      • 仍然没有工作:(,我确定类内的 post 函数存在一些问题,因为当我使用直接 axios 而没有创建它正在工作的实例时
      猜你喜欢
      • 2021-11-17
      • 2017-08-14
      • 2019-07-02
      • 2020-05-22
      • 1970-01-01
      • 2021-01-19
      • 2021-09-03
      • 2022-12-10
      • 2019-11-20
      相关资源
      最近更新 更多