如何用泛型转换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
相关产品推荐
相关产品推荐

