TypeScript中键名不同的对象类型互转及键映射的推荐方案
TypeScript 同结构异名字段对象双向转换方案
以下是两种生产环境常用的类型安全实现方式,均可以保证编译阶段的类型校验:
基础实现:专用转换函数(无额外依赖,推荐绝大多数场景使用)
首先明确两种类型定义:
// 后端要求的标签类型 type TagTypeThatMyBackendWants = { id: string; name: string; } // 第三方库要求的标签类型 type TagTypeThatALibraryWants = { id: string; text: string; }
直接编写双向转换函数,逻辑透明无运行时开销,完全类型安全:
// 后端类型转第三方库类型 const toLibraryTag = (backendTag: TagTypeThatMyBackendWants): TagTypeThatALibraryWants => { return { id: backendTag.id, text: backendTag.name }; }; // 第三方库类型转回后端类型 const toBackendTag = (libraryTag: TagTypeThatALibraryWants): TagTypeThatMyBackendWants => { return { id: libraryTag.id, name: libraryTag.text }; }; // 可按需扩展数组批量转换方法 const toLibraryTagList = (tags: TagTypeThatMyBackendWants[]) => tags.map(toLibraryTag); const toBackendTagList = (tags: TagTypeThatALibraryWants[]) => tags.map(toBackendTag);
通用实现:转换工厂函数(适合多同类场景复用)
如果项目中存在大量仅字段名不同的类型互转需求,可以封装通用转换工具,提前声明字段映射关系即可复用逻辑:
// 通用字段映射规则类型 type FieldMapping<Source, Target> = { [K in keyof Target]: keyof Source | ((source: Source) => Target[K]) }; // 转换函数生成工厂 function createConverter<Source, Target>(mapping: FieldMapping<Source, Target>) { return (sourceObj: Source): Target => { return Object.entries(mapping).reduce((target, [targetKey, rule]) => { // @ts-ignore 类型合法性由外部FieldMapping泛型保证 target[targetKey] = typeof rule === "function" ? rule(sourceObj) : sourceObj[rule]; return target; }, {} as Target); }; } // 声明当前场景的双向映射关系 const backendToLibMapping: FieldMapping<TagTypeThatMyBackendWants, TagTypeThatALibraryWants> = { id: "id", text: "name" }; const libToBackendMapping: FieldMapping<TagTypeThatALibraryWants, TagTypeThatMyBackendWants> = { id: "id", name: "text" }; // 生成转换函数 const toLibraryTag = createConverter(backendToLibMapping); const toBackendTag = createConverter(libToBackendMapping);
内容的提问来源于stack exchange,提问作者Swiffy
相关产品推荐
相关产品推荐

