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

TypeScript中如何将映射泛型类型转为元组联合?实现强类型Object.entries

实现强类型约束的Object.entries类型

要让Entries<T>返回每个属性键值对一一对应的二元元组联合,你需要利用TypeScript的分布式条件类型和映射类型来逐个处理对象的每个属性,而不是直接取keyof T和对应的联合值。

正确的类型定义

export type Entries<T> = {
  [K in keyof T]: [K, T[K]];
}[keyof T][];

效果验证

当你使用Entries<{first: number, second: string}>时,得到的类型会是:

(["first", number] | ["second", string])[]

完全符合你的预期——数组中的每个元素都是对应属性的精确键值元组,不会出现键值不匹配的情况。

为什么原来的实现不行?

原来的[keyof T, T[keyof T]][]会把keyof T解析成所有键的联合类型,T[keyof T]解析成所有值的联合类型,两者是独立的,所以最终会得到(键联合, 值联合)的元组数组,导致可能出现["first", string]这种不符合实际的类型组合。

拆解实现逻辑

  1. 首先用映射类型{ [K in keyof T]: [K, T[K]] }遍历T的每个属性K,为每个属性生成对应的[键, 值]元组类型,得到一个新的对象类型。比如对于{first: number, second: string},这个映射后的类型是:
    {
      first: ["first", number];
      second: ["second", string];
    }
    
  2. 然后通过[keyof T]索引这个对象类型,取出所有属性值的联合类型,也就是["first", number] | ["second", string];
  3. 最后加上[]把这个联合类型变成数组,就得到了每个元素都是精确键值对的数组类型。

额外优化:处理可选属性

如果你的对象包含可选属性,上面的类型会把可选属性的元组也包含进来,但值可能是undefined。这里提供两种常见的处理方式:

过滤可选属性

export type Entries<T> = {
  [K in keyof T]-?: [K, T[K]];
}[keyof T][];

这里的-?是移除属性的可选标记,确保每个元组的值都是非undefined的(前提是原属性的类型本身不包含undefined),这更贴近Object.entries的实际运行时行为——未赋值的可选属性不会被遍历到。

保留可选属性并明确值类型

如果你想保留可选属性,但让值类型明确包含undefined,可以用:

export type Entries<T> = {
  [K in keyof T]: [K, Required<T>[K] | undefined];
}[keyof T][];

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:49:01