如何用TypeScript映射类型实现混合预定义与自定义变量的键值对象
实现支持混合类型数组的TypeScript映射类型
完全可行,你可以通过条件类型和键重映射实现这个需求,同时结合元组类型推断保留数组元素的具体类型信息。以下是具体实现方案:
1. 定义基础类型与键提取工具
首先明确数组允许的元素类型,以及用于提取键的工具类型:
// 数组元素类型:字符串 或 含name属性的对象 type MappableItem = string | { name: string }; // 提取元素对应的键:字符串直接用自身,对象取name属性值 type ExtractKey<T extends MappableItem> = T extends string ? T : T extends { name: infer N } ? N : never;
2. 构建映射类型
利用TypeScript的键重映射(as关键字),将数组元素转换为对象的键:
// 最终的映射对象类型:键为提取出的字符串,值类型可根据需求自定义 type MappedResult<T extends MappableItem[]> = { [K in T[number] as ExtractKey<K>]: unknown; // 若需要不同元素对应不同值类型,可改为: // [K in T[number] as ExtractKey<K>]: K extends string ? string : number; };
3. 辅助函数生成对象
写一个工具函数,接收混合类型数组并返回符合类型约束的对象:
function createMappedObject<T extends MappableItem[]>(items: [...T]): MappedResult<T> { return items.reduce((obj, item) => { const key = typeof item === 'string' ? item : item.name; // 这里可根据业务逻辑赋值,示例用undefined占位 obj[key] = undefined; return obj; }, {} as MappedResult<T>); }
4. 测试示例
// 传入混合类型数组 const mixedResult = createMappedObject(['user', { name: 'order' }, 'product', { name: 'cart' }]); // 类型推断结果:{ user: unknown; order: unknown; product: unknown; cart: unknown } // 访问时会有类型提示,比如mixedResult.user是合法的,mixedResult.invalid则会报错
核心逻辑说明:
- 使用
[...T]元组类型参数,让TypeScript能精准推断数组中每个元素的具体类型,而非统一视为MappableItem - 通过
as ExtractKey<K>在映射时动态生成对象键 - 辅助函数里通过类型判断处理两种元素,确保运行时逻辑和类型定义一致
内容的提问来源于stack exchange,提问作者Even A. Rognlien
相关产品推荐
相关产品推荐

