TypeScript中如何优雅转换API返回模型为业务模型类型?
类型安全的API模型到业务模型转换方案
基础接口定义
先明确核心结构和示例模型:
// API返回通用结构(日期为字符串格式) interface APIModelCommon { createdAt: string; updatedAt: string; } // 业务侧通用结构(日期为Date对象) interface ModelCommon { createdAt: Date; updatedAt: Date; } // 示例API模型 interface APIArchive extends APIModelCommon { id: number; name: string; content: string; } // 示例业务模型 interface Archive extends ModelCommon { id: number; name: string; content: string; }
核心实现:类型映射+安全转换函数
通过TypeScript的类型工具和泛型,构建严格的类型转换关系,避免粗暴的强制类型断言:
1. 定义API到业务模型的类型映射
// 自动将API模型转换为对应业务模型的类型 type ApiToBusiness<T extends APIModelCommon> = Omit<T, keyof APIModelCommon> & ModelCommon;
这个类型会自动移除API模型中的createdAt/updatedAt字段,再与ModelCommon合并,生成符合业务要求的模型类型。
2. 编写类型安全的转换函数
function convertApiModel<T extends APIModelCommon>(apiModel: T): ApiToBusiness<T> { return { // 保留API模型中除日期外的所有字段 ...apiModel, // 将字符串日期转换为Date对象 createdAt: new Date(apiModel.createdAt), updatedAt: new Date(apiModel.updatedAt) }; }
使用示例
调用函数时,TypeScript会自动推导返回值类型,完全匹配业务模型:
const apiData: APIArchive = { id: 1, name: "项目归档", content: "归档内容详情", createdAt: "2024-05-20T14:30:00Z", updatedAt: "2024-05-21T09:15:00Z" }; const businessData = convertApiModel(apiData); // businessData类型为Archive,createdAt/updatedAt均为Date类型,无类型错误
扩展:支持自定义字段转换
如果部分模型需要额外字段转换,可以扩展函数,添加可选的自定义转换回调,此时的类型断言是可控且安全的:
function convertApiModel<T extends APIModelCommon, U extends ApiToBusiness<T> = ApiToBusiness<T>>( apiModel: T, customTransform?: (baseFields: Omit<T, keyof APIModelCommon>) => Partial<Omit<U, keyof ModelCommon>> ): U { // 提取非日期字段 const { createdAt, updatedAt, ...baseFields } = apiModel; // 应用自定义转换(如果有) const transformedBase = customTransform ? { ...baseFields, ...customTransform(baseFields) } : baseFields; return { ...transformedBase, createdAt: new Date(createdAt), updatedAt: new Date(updatedAt) } as U; }
方案优势
- 完全利用TypeScript类型系统,无需
as unknown as T这类粗暴的强制断言 - 类型映射自动推导,新增模型时无需重复编写转换逻辑
- 代码简洁可读,同时保证端到端的类型安全
内容的提问来源于stack exchange,提问作者Spedwards
相关产品推荐
相关产品推荐

