You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 21:15:44