TypeScript中API响应JSON数据的泛型类型映射异常问题
解决API响应序列化与反序列化的类型不匹配问题
你的问题核心出在Stringified<T>泛型的类型判断逻辑上,主要有两个问题:
Date在TypeScript中属于object子类型,会被原逻辑误判为对象进行递归处理,导致Date类型被解析成Stringified<Date>而非string;- 数组类型的处理逻辑错误,原代码直接对数组类型递归
Stringified<T[key]>,而不是对数组元素进行类型转换。
修正后的Stringified<T>泛型
重新调整类型判断的优先级,先处理Date和数组类型,再处理普通对象:
type Stringified<T> = // 优先处理Date类型,直接映射为string T extends Date ? string : // 处理数组:提取元素类型U,对每个元素应用Stringified后组成数组 T extends Array<infer U> ? Stringified<U>[] : // 处理普通对象:递归映射每个属性 T extends object ? { [K in keyof T]: Stringified<T[K]> } : // 数字、布尔类型保持原类型 T extends number | boolean ? T : // 其他类型统一转为string string;
修正后的API响应类型
替换原有的ApiResponse定义即可:
type ApiResponse<T> = { success: true; data: Stringified<T> } | { success: false; errors: string[] }
验证hydrateEvent函数
此时Stringified<Event>会正确解析响应类型:
start/end字段被识别为string;visibility字段被解析为嵌套的Stringified<{ host: boolean; bands: boolean; public: boolean }>,和Event['visibility']结构完全匹配。
修正后的hydrateEvent函数不再有类型错误:
type Event = { id: string; name: string; start: Date; end: Date; visibility?: { host: boolean, bands: boolean, public: boolean } } function hydrateEvent(rawEvent: Stringified<Event>){ const event: Event = { id: rawEvent.id, name: rawEvent.name, start: new Date(rawEvent.start), end: new Date(rawEvent.end) }; if(rawEvent.visibility){ event.visibility = rawEvent.visibility; } return event; }
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

