TypeScript如何将对象数组类型转换为id为键value为值的对象类型
TypeScript 实现数组转精确键值对象类型方案
完全可以实现,核心依赖TypeScript 4.1及以上版本支持的**映射类型键重映射(Key Remapping)**特性,具体实现如下:
正确类型定义
首先修正你原有类型的小问题:直接写type MyArray = MyObject[]会丢失泛型的精确类型信息,因为MyObject是泛型接口,未传泛型参数时value会被推断为any。转换类型的完整写法:
// 基础对象类型保持原有定义即可 interface MyObject<T> { id: string value: T } /** * 把MyObject组成的数组转换为键为id、值为对应value的精确对象类型 * 泛型约束T必须是由MyObject元素组成的数组/元组 */ type MyArrayObject<T extends readonly MyObject<any>[]> = { [K in T[number] as K['id']]: K['value'] }
语法说明
- 泛型参数加
readonly约束是为了兼容as const声明的常量元组,这是拿到精确字面量类型的必要前提 K in T[number]:遍历数组中所有元素的类型as K['id']:键重映射语法,将当前遍历元素的id字面量类型作为最终对象的键- 值类型直接取当前元素的
value属性即可,不需要额外调用typeof
示例用法
对应你给出的场景,使用时需要给数组加上as const,让TS保留精确的字面量类型,否则会被推导为宽泛的string/联合类型:
// 加as const保留字面量类型,satisfies做类型校验不丢失字面量信息 const arr = [ { id: "key1", value: 123 }, { id: "key2", value: "abc" } ] as const satisfies readonly MyObject<any>[] // 生成目标对象类型 type ArrObjectType = MyArrayObject<typeof arr> // 等价于类型:{ key1: 123; key2: "abc" } // 类型校验完全符合预期 const arrObject: ArrObjectType = { "key1": 123, "key2": "abc" }
注意点
你原本预想的interface索引签名写法无法实现这个需求:TS中接口的索引签名参数类型只能是string/number/symbol/模板字面量类型这类通用类型,不支持传入具体的字面量联合作为键,必须用映射类型(type关键字定义)实现。
内容的提问来源于stack exchange,提问作者Jonas Mærsk
相关产品推荐
相关产品推荐

