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

如何用泛型转换TypeScript对象类型并保留键值关系?

TypeScript 通过泛型转换对象类型为键值联合结构

针对你提出的两种转换需求,我们可以结合映射类型和索引访问类型来实现,核心思路是先通过映射类型为每个键生成目标结构,再通过索引访问提取所有结构组成联合类型。

1. 转换为键值对象联合类型

定义如下泛型即可实现:

type KeyValueObject<T> = {
  [K in keyof T]: { key: K; value: T[K] }
}[keyof T];

原理说明:

  • [K in keyof T]:遍历传入类型T的所有键K,为每个键生成对应的{ key: K; value: T[K] }结构,此时会得到一个类似{ foo: { key: 'foo', value: string }, bar: { key: 'bar', value: number }, ... }的对象类型。
  • [keyof T]:通过索引访问该对象的所有键,提取出所有属性值的类型,自动组合成联合类型。

用你的interface A测试:

interface A {
  foo: string;
  bar: number;
  baz: boolean;
}

type Result = KeyValueObject<A>;
// 等价于:
// | { key: 'foo'; value: string; }
// | { key: 'bar'; value: number; }
// | { key: 'baz'; value: boolean; }

2. 转换为键值对函数联合类型

调整映射结构为函数类型,同样的思路可以实现需求:

type KeyValueHandler<T> = {
  [K in keyof T]: (key: K, value: T[K]) => Promise<T[K]>
}[keyof T];

原理说明:

  • 通过[K in keyof T]遍历每个键,为每个键生成对应的函数类型:参数匹配键的字面量类型和对应值类型,返回值为对应值类型的Promise。
  • 最后通过[keyof T]提取所有函数类型,组成联合类型。

用interface A测试:

type HandlerResult = KeyValueHandler<A>;
// 等价于:
// | (key: 'foo', value: string) => Promise<string>
// | (key: 'bar', value: number) => Promise<number>
// | (key: 'baz', value: boolean) => Promise<boolean>

为什么单纯映射类型不行?

单纯的映射类型只会生成一个包含所有目标结构的对象类型,而我们需要的是这些结构的联合类型,因此必须通过[keyof T]索引访问,把对象的所有属性值类型“拉出来”组合成联合。

内容的提问来源于stack exchange,提问作者hon2a

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 22:13:29