VDone Demo VDone Demo
Home
  • Articles

    • JavaScript
  • Study Notes

    • JavaScript Tutorial
    • Professional JavaScript
    • ES6 Tutorial
    • Vue
    • React
    • TypeScript: Build Axios from Scratch
    • Git
    • TypeScript
    • JS Design Patterns
  • HTML
  • CSS
  • Technical Docs
  • GitHub Tips
  • Node.js
  • Blog Setup
  • Learning
  • Interviews
  • Miscellaneous
  • Practical Tips
  • Friends
About
Bookmarks
  • Categories
  • Tags
  • Archives
GitHub (opens new window)

Nikolay Tuzov

Backend Developer
Home
  • Articles

    • JavaScript
  • Study Notes

    • JavaScript Tutorial
    • Professional JavaScript
    • ES6 Tutorial
    • Vue
    • React
    • TypeScript: Build Axios from Scratch
    • Git
    • TypeScript
    • JS Design Patterns
  • HTML
  • CSS
  • Technical Docs
  • GitHub Tips
  • Node.js
  • Blog Setup
  • Learning
  • Interviews
  • Miscellaneous
  • Practical Tips
  • Friends
About
Bookmarks
  • Categories
  • Tags
  • Archives
GitHub (opens new window)
  • 初识 TypeScript

  • TypeScript 常用语法

  • ts-axios 项目初始化

  • ts-axios 基础功能实现

  • ts-axios 异常情况处理

  • ts-axios 接口扩展

    • Extending Interfaces
    • axios Function Overloading
    • Generic Support for Response Data
      • Requirements Analysis
      • Adding Generic Parameters to Interfaces
      • Writing the Demo
  • ts-axios 拦截器实现

  • ts-axios 配置化实现

  • ts-axios 取消功能实现

  • ts-axios 更多功能实现

  • ts-axios 单元测试

  • ts-axios 部署与发布

  • 《TypeScript 从零实现 axios》
  • ts-axios 接口扩展
HuangYi
2020-01-05
Contents

Generic Support for Response Data

# Generic Support for Response Data

# Requirements Analysis

Typically, we place the backend return data format in a separate interface:

// Request interface data
export interface ResponseData<T = any> {
  /**
   * Status code
   * @type { number }
   */
  code: number

  /**
   * Data
   * @type { T }
   */
  result: T

  /**
   * Message
   * @type { string }
   */
  message: string
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

We can extract the API into a separate module:

import { ResponseData } from './interface.ts';

export function getUser<T>() {
  return axios.get<ResponseData<T>>('/somepath')
    .then(res => res.data)
    .catch(err => console.error(err))
}
1
2
3
4
5
6
7

Then we specify the return data type User, which allows TypeScript to correctly infer the type we want:

interface User {
  name: string
  age: number
}

async function test() {
  // user is inferred as
  // {
  //  code: number,
  //  result: { name: string, age: number },
  //  message: string
  // }
  const user = await getUser<User>()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# Adding Generic Parameters to Interfaces

Based on the requirements analysis, we need to add generic parameters to the relevant interface definitions.

types/index.ts:

export interface AxiosResponse<T = any> {
  data: T
  status: number
  statusText: string
  headers: any
  config: AxiosRequestConfig
  request: any
}

export interface AxiosPromise<T = any> extends Promise<AxiosResponse<T>> {
}

export interface Axios {
  request<T = any>(config: AxiosRequestConfig): AxiosPromise<T>

  get<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>

  delete<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>

  head<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>

  options<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>

  post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>

  put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>

  patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>
}

export interface AxiosInstance extends Axios {
  <T = any>(config: AxiosRequestConfig): AxiosPromise<T>

  <T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

Here we first added a generic parameter T to the AxiosResponse interface, where T=any means the default value of the generic type parameter is any.

Then we added generic parameters to the AxiosPromise, Axios, and AxiosInstance interfaces. We can see that the return types of all these requests have become AxiosPromise<T>, which is Promise<AxiosResponse<T>>. This way, we can retrieve the type T from the response.

# Writing the Demo

examples/extend/app.ts:

interface ResponseData<T = any> {
  code: number
  result: T
  message: string
}

interface User {
  name: string
  age: number
}

function getUser<T>() {
  return axios<ResponseData<T>>('/extend/user')
    .then(res => res.data)
    .catch(err => console.error(err))
}


async function test() {
  const user = await getUser<User>()
  if (user) {
    console.log(user.result.name)
  }
}

test()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

When we call getUser<User>, it is equivalent to calling axios<ResponseData<User>>, meaning the type T we pass to the axios function is ResponseData<User>. This is equivalent to T in the return value AxiosPromise<T>, which is actually the T in Promise<AxiosResponse<T>> being of type ResponseData<User>. So the data type in the response data is ResponseData<User>, which has the following data structure:

{
  code: number
  result: User
  message: string
}
1
2
3
4
5

This is also the data type of the return value user from const user = await getUser<User>(), so TypeScript can correctly infer the type of user.

At this point, our ts-axios interface extensions chapter is complete. In the next chapter, we will implement a very useful feature of axios -- interceptors.

Edit (opens new window)
#TypeScript
Last Updated: 2026/03/21, 12:14:36
axios Function Overloading
Interceptor Design and Implementation

← axios Function Overloading Interceptor Design and Implementation→

Recent Updates
01
How I Discovered Disposable Email — A True Story
06-12
02
Animations in Grid Layout
09-15
03
Renaming a Git Branch
08-11
More Articles >
Theme by VDone | Copyright © 2026-2026 Nikolay Tuzov | MIT License | Telegram
  • Auto
  • Light Mode
  • Dark Mode
  • Reading Mode