基于RxJS扩展方法封装订阅以返回新模型的技术疑问
自定义API响应的Angular类型处理问题
背景与现有实现
我接手的API所有端点都会返回自定义的Response包装对象,于是在Angular项目的TypeScript中定义了对应类型:
export class Response<T> { code: number; data: T; message?: string; }
直接调用API时,虽然在HttpClient.post里指定了泛型,但返回的响应实际是Object类型,没有真正的类型实例化:
import { HttpClient } from '@angular/common/http'; this.http.post<Response<Data>>(url, payload).subscribe({ // 这里仅IDE能识别Data类型 next: (response) => { if (response.code === 200) { this.data = response.data; // response.data实际是Object,无类型约束 } } })
为了实现类型校验和统一错误处理,我尝试封装了一个typeSubscribe扩展方法,期望能自动处理响应并返回正确类型的data:
export function typeSubscribe<T>( this: Observable<Response<T>>, next?: (value: T) => void, error?: (error: T) => void, complete?: () => void ): Subscription { let newNext: (value: T) => void = next; if (next) { newNext = (value: T): void => { value = buildReponse<T>(value); if (value.code !== 200) { error(value.message); return; } next(value.data); }; } const sub = this.subscribe({ next: newNext, error, complete }); return sub; } function buildReponse<T>(body: any): Response<T> { const response = new Response<T>(); if (!body) { response.code = 500; response.message = 'Response is empty'; response.data = null; return response; } response.code = body.code; response.message = body.message; response.data = map<T>(body.data, body.data.constructor); // 尝试用body.data的构造函数实例化类型 return response; } // 当前仅返回空对象,未正确映射属性 function map<T>(values: any, ctor: new () => T): T { const instance = new ctor(); return Object.keys(instance).reduce((acc: any, key: string) => { acc[key] = values[key]; return acc; }, {}) as T; }
预期使用方式:
this.http.post<Response<Data>>(url, payload).typeSubscribe((response) => { this.data = response; // 期望response是完整类型化的Data })
技术疑问
typeSubscribe仅能在IDE的IntelliSense中识别T类型,运行时无法获取T的类型信息,怎么才能从HTTP响应中真正实例化TypeScript类型?- 能不能让Observable的类型是
Response<T>,但subscribe的next回调直接返回T(也就是Response.data)?二者类型可以不一致吗?
内容的提问来源于stack exchange,提问作者jcc
相关产品推荐
相关产品推荐

