TypeScript泛型实战:企业级请求封装全解析

TypeScript 泛型与工具类型实战:企业级通用数据请求封装完整案例

一、文档概述

在前端项目开发中,网络请求是高频基础能力。传统JavaScript封装的请求函数存在类型缺失、参数与返回值无校验、复用性差等问题。TypeScript凭借泛型 实现类型复用,结合内置工具类型约束参数、过滤字段、规范返回结构,可打造出类型安全、可拓展、适配企业级业务的通用请求工具。本文基于Axios,结合TS泛型、常用工具类型完成通用请求封装,并讲解核心知识点与落地用法。

二、前置依赖

项目需安装基础依赖,执行以下命令:

bash 复制代码
npm install axios typescript @types/axios -S

三、核心类型定义

首先定义请求基础枚举、通用接口,使用PartialRequiredPick等TS工具类型约束配置项,统一请求格式。

typescript 复制代码
// 请求方法枚举
export enum RequestMethod {
  GET = "GET",
  POST = "POST",
  PUT = "PUT",
  DELETE = "DELETE"
}

// 基础请求配置
interface BaseRequestConfig {
  url: string;
  method: RequestMethod;
  timeout?: number;
  headers?: Record<string, string>;
}

// 使用工具类型:必填请求核心字段,可选拓展字段
type FullRequestConfig = Required<Pick<BaseRequestConfig, "url" | "method">> & Partial<Omit<BaseRequestConfig, "url" | "method">>;

// 统一后端返回格式
export interface ApiResponse<T> {
  code: number;
  message: string;
  data: T;
  success: boolean;
}

知识点说明

  1. Required:将接口所有可选属性转为必选;
  2. Pick:从类型中挑选指定属性生成新类型;
  3. Omit:剔除类型中指定属性;
  4. Partial:将接口所有必选属性转为可选。

四、通用请求函数封装

利用泛型 <T> 动态约束接口返回data的类型,实现不同接口独立类型校验,同时统一拦截器、超时、异常处理逻辑。

typescript 复制代码
import axios, { AxiosRequestConfig, AxiosError } from "axios";

// 创建axios实例
const service = axios.create({
  baseURL: "/api",
  timeout: 10000
});

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    // 统一添加Token
    config.headers.Authorization = `Bearer ${localStorage.getItem("token") || ""}`;
    return config;
  },
  (error: AxiosError) => Promise.reject(error)
);

// 响应拦截器
service.interceptors.response.use(
  (res) => res.data,
  (error: AxiosError) => {
    console.error("请求异常:", error.message);
    return Promise.reject(error);
  }
);

/**
 * 通用请求函数(泛型实现类型动态匹配)
 * @param config 请求配置
 * @returns 后端结构化返回数据
 */
export function request<T>(config: FullRequestConfig): Promise<ApiResponse<T>> {
  const axiosConfig: AxiosRequestConfig = {
    url: config.url,
    method: config.method,
    timeout: config.timeout,
    headers: config.headers
  };
  return service(axiosConfig);
}

五、业务接口调用演示

基于封装的通用请求函数,模拟用户查询新增用户两个业务接口,演示泛型在实际业务中的使用,全程拥有完整代码提示与类型校验。

typescript 复制代码
// 定义用户实体类型
export interface UserInfo {
  id: number;
  username: string;
  age: number;
  phone: string;
}

// 1. 获取用户详情接口
async function getUserDetail(userId: number) {
  // 泛型指定返回data为UserInfo类型
  const res = await request<UserInfo>({
    url: `/user/detail?id=${userId}`,
    method: RequestMethod.GET
  });
  if (res.success) {
    console.log("用户信息:", res.data.username, res.data.age);
  }
}

// 2. 新增用户接口
async function addUser(user: Omit<UserInfo, "id">) {
  const res = await request<boolean>({
    url: "/user/add",
    method: RequestMethod.POST,
    headers: {
      "Content-Type": "application/json"
    }
  });
  if (res.success && res.data) {
    console.log("新增用户成功");
  }
}

// 调用测试
getUserDetail(1);
addUser({ username: "test", age: 22, phone: "13800138000" });

核心亮点 :调用接口时通过泛型<T>绑定业务类型,编辑器可自动提示字段,编译阶段即可发现参数、返回值类型错误,规避线上BUG。

六、总结

  1. 泛型解决了请求函数类型复用 问题,让不同接口拥有独立类型约束,告别any滥用;
  2. TypeScript工具类型可灵活裁剪、改造配置类型,简化重复类型编写,统一项目类型规范;
  3. 基于Axios+TS封装的通用请求,兼顾统一性、安全性与拓展性,完全适配中大型企业前端项目。

该方案可在此基础上拓展文件上传、分页请求、请求防抖等功能,整体架构稳定且易维护。

海量精选技术文档和实战案例持续更新,敬请关注【风骏时光少年】

相关推荐
BomanGe21 小时前
NSK直线导轨LH55EL与NH55EM替代指南
前端·javascript·数据库·经验分享·规格说明书
云水一下1 小时前
Vue.js从零到精通系列(四):前端路由与Vue Router——打造多页单页应用
前端·javascript·vue.js
研☆香2 小时前
jQuery补充知识点
前端·javascript·jquery
先吃饱再说2 小时前
JavaScript栈和队列:从“冰柜里的雪糕”到“排队打饭”
javascript·数据结构
crack_comet2 小时前
修复 Claude Code TypeScript LSP 在 Windows 上启动失败的问题
windows·typescript·里氏替换原则
槑有老呆2 小时前
JavaScript 数组,远不止 [] 那么简单
javascript
HjhIron2 小时前
从栈到队列,再到链表:前端开发者必知的线性数据结构
前端·javascript
阿猫的故乡2 小时前
Vue自定义指令从入门到实用:自动聚焦、权限控制、防抖、懒加载……全案例教学
前端·javascript·vue.js
该用户已成仙2 小时前
vue3 使用 vuedraggable 报错 TypeError: isFunction2 is not a function
前端·javascript·vue.js