TypeScript编写可转换函数及自定义类AngularJS风格$http服务问询
嘿,我来帮你梳理这两个问题——先说说TypeScript里怎么写可转换函数,再聊聊你的自定义$http服务优化思路~
一、TypeScript中编写可转换函数的核心思路
可转换函数的核心是在类型安全的前提下,把一种数据结构/类型转换成另一种,尤其适合API响应转业务实体、数据格式适配这类场景。这里给你几个实用的写法思路:
用泛型明确输入输出类型
泛型能让函数复用性更强,同时保证类型检查。比如写一个通用转换函数,支持不同类型的转换逻辑:// 泛型转换函数:接受原始数据和具体转换逻辑 function transform<T>(rawData: unknown, converter: (data: unknown) => T): T { try { return converter(rawData); } catch (error) { console.error('转换失败:', error); throw error; // 或返回默认值,根据业务需求调整 } }结合类型守卫保证安全
因为前端经常会收到不确定结构的API数据,用类型守卫可以避免转换时的类型错误:interface Product { id: number; name: string; price: number; } // 专门的Product转换逻辑,带类型守卫 function toProduct(raw: unknown): Product { // 检查原始数据结构是否合法 if (!raw || typeof raw !== 'object' || !('id' in raw) || !('name' in raw) || !('price' in raw)) { throw new Error('无效的Product原始数据'); } // 类型断言+字段格式转换 return { id: Number(raw.id), name: String(raw.name).trim(), price: Number(raw.price) || 0 }; } // 使用示例 const rawProduct = { id: '456', name: ' Wireless Headset ', price: '199.99' }; const product = transform<Product>(rawProduct, toProduct);处理边界情况
别忘了处理空值、异常数据,比如给可选字段设置默认值,或者捕获转换中的错误,避免程序崩溃。
二、自定义AngularJS风格$http服务的优化建议
从你贴的代码片段来看,已经搭好了基础框架(默认配置、method校验、GET请求处理),这里给你几个贴合AngularJS风格且更健壮的优化方向:
1. 完善参数与配置处理
- 自动转换GET参数:支持直接传入对象作为params,不用手动创建HttpParams:
case this.httpMethods.get: // 把对象格式的params自动转为HttpParams const params = config.params ? new HttpParams({ fromObject: config.params as Record<string, string | number> }) : new HttpParams(); return this.http.get(config.url, { params, headers: config.headers }); - 深度合并默认配置:用
Object.assign把用户传入的config和默认配置合并,而不是简单覆盖,比如:private _generateHttpConfig(): CustomHttpConfig { return { method: this.httpMethods.get, headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; } // 在方法开头合并配置 const mergedConfig = { ...this._generateHttpConfig(), ...config };
2. 优化Observable的使用
- 避免手动创建Observable:尽量复用Angular HttpClient返回的Observable,它自带取消、重试等RxJS特性。比如URL校验失败可以用
throwError:if (!mergedConfig.url) { console.error("Error: [$http:badreq]", mergedConfig); return throwError(() => this._ubiConstants.messages.genericErrorKey); } - 统一错误处理:用
pipe(catchError())全局处理HTTP错误,模拟AngularJS$http的错误回调风格:import { catchError } from 'rxjs/operators'; // 在请求返回后添加错误处理 return this.http.get(...) .pipe( catchError(error => { console.error("HTTP请求失败:", error); return throwError(() => this._ubiConstants.messages.httpErrorKey); }) );
3. 模拟AngularJS$http的核心特性
- 添加快捷方法:像AngularJS那样提供
$http.get()、$http.post()等快捷方法,不用每次传method:get(url: string, config?: Omit<CustomHttpConfig, 'method' | 'url'>): Observable<any> { return this.$http({ ...config, method: this.httpMethods.get, url }); } post(url: string, body: any, config?: Omit<CustomHttpConfig, 'method' | 'url' | 'body'>): Observable<any> { return this.$http({ ...config, method: this.httpMethods.post, url, body }); } - 支持拦截器:创建拦截器数组,在请求发送前和响应返回后执行逻辑(比如添加token、修改响应数据),贴近AngularJS的拦截器机制:
private interceptors: Array<{ request?: (config: CustomHttpConfig) => CustomHttpConfig; response?: (data: any) => any }> = []; // 添加拦截器方法 addInterceptor(interceptor: any) { this.interceptors.push(interceptor); } // 在请求前执行拦截器 const interceptedConfig = this.interceptors.reduce((cfg, interceptor) => { return interceptor.request?.(cfg) || cfg; }, mergedConfig);
4. 强化类型定义
给CustomHttpConfig添加更精确的类型约束,避免传参错误:
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'; interface CustomHttpConfig { method?: HttpMethod; url?: string; params?: Record<string, string | number | boolean>; headers?: HttpHeaders | Record<string, string>; body?: any; }
内容的提问来源于stack exchange,提问作者Sampgun
相关产品推荐
相关产品推荐

