如何在TypeScript Web API客户端中创建响应处理装饰器?
将API响应处理逻辑转为装饰器的实现方案
嘿,我来帮你把原来的response方法改写成装饰器,这样你就能摆脱重复调用this.response的麻烦,让代码更简洁!下面是具体的实现步骤和完整代码:
第一步:准备装饰器基础与类型
首先,确保你的TypeScript配置文件(tsconfig.json)里开启了experimentalDecorators和emitDecoratorMetadata,这是使用装饰器的必要前提。
接下来我们实现封装响应逻辑的装饰器函数,它会接管原方法的响应处理工作:
// 先定义你的ResponseError类型(保持你原有逻辑的结构即可) type ResponseError = { message: string; statusCode: number; }; // 实现响应处理装饰器 function HandleResponse() { return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) { // 保存原方法的引用,避免覆盖 const originalMethod = descriptor.value; // 重写方法的执行逻辑 descriptor.value = async function(...args: any[]) { try { // 调用原API方法,获取Axios响应对象 const res = await originalMethod.apply(this, args); // 调用类内部的hasError方法检查状态码 const err = this.hasError(res.status); if (err) { return err; } // 无错误则返回响应数据 return res.data; } catch (axiosError) { // 额外处理Axios请求本身的异常(比如网络错误、请求超时) return { message: axiosError.message || 'Request failed unexpectedly', statusCode: axiosError.response?.status || 500 } as ResponseError; } }; return descriptor; }; }
第二步:改造Client类
现在可以删掉原来的response方法,用@HandleResponse()装饰器直接修饰你的API请求方法:
import axios, { AxiosResponse } from 'axios'; // 假设你的SomeData类型定义 type SomeData = { id: number; content: string; }; // 示例其他数据类型 type AnotherData = { name: string; value: number; }; class Client { private hasError(statusCode: number): ResponseError | null { // 保留你原来的错误判断逻辑 if (statusCode >= 400) { return { message: `HTTP Error: ${statusCode}`, statusCode }; } return null; } @HandleResponse() public async getSomeData(): Promise<SomeData | ResponseError> { // 现在只需专注于发起请求,响应处理交给装饰器 return axios.get("/api/endpoint"); } // 其他API方法也可以直接复用这个装饰器 @HandleResponse() public async getAnotherData(): Promise<AnotherData | ResponseError> { return axios.get("/api/another-endpoint"); } }
第三步:逻辑说明
- 装饰器
HandleResponse会自动包裹目标方法,先执行原方法获取Axios响应,再调用类内部的hasError做状态校验。 - 校验不通过时返回
ResponseError,校验通过则直接返回响应数据,完全替代了原来response方法的作用。 - 新增的
try/catch可以处理请求本身的异常(比如网络中断),让错误覆盖更全面。 - 所有API方法只需关注请求本身,响应处理逻辑统一由装饰器维护,代码更简洁、易扩展。
内容的提问来源于stack exchange,提问作者Junya Kono
相关产品推荐
相关产品推荐

