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

如何修复TypeScript中Object.fromEntries定义以支持联合类型键?

修复TypeScript中Object.fromEntries的联合类型键推断问题

之前为Object.fromEntries定义了如下类型声明,在元组首元素为唯一类型时可以正常工作,但当元组首元素是联合类型时会推断失败:

declare global {
  interface ObjectConstructor {
    fromEntries<
      A extends ReadonlyArray<readonly [PropertyKey, any]>
    >(array: A): { [K in A[number][0]]: Extract<A[number], readonly [K, any]>[1] }
  }
}

示例代码及问题表现:

const x = Object.fromEntries(
  [['a', 1], ['b', 2], ['c', 'foo']] as (['a' | 'b', number] | ['c', string])[]
);
// 错误推断结果:typeof x = { a: never, b: never; c: string; }

问题根源在于,当遍历A[number][0]中的单个键(比如'a'或'b')时,Extract<A[number], readonly [K, any]>无法匹配['a' | 'b', number]这个联合元组——因为'a' | 'b'并不继承自单个的'a'或'b',导致对应值类型被推断为never。


解决方案

通过分布式条件类型遍历每个联合元组成员,先将每个元组转换为单个键值对对象,再合并这些对象类型,修复后的声明如下:

declare global {
  interface ObjectConstructor {
    fromEntries<
      T extends readonly [PropertyKey, unknown][]
    >(entries: T): MergeUnion<{
      [U in T[number]]: U extends readonly [infer K, infer V] ? { [P in K]: V } : never
    }>
  }
}

// 辅助类型:合并联合类型中的多个对象类型
type MergeUnion<T> = T extends infer U ? { [K in keyof U]: U[K] } : never;

原理说明

  1. 利用TypeScript的分布式特性遍历输入元组数组的每个联合成员U;
  2. 对每个U提取键K和值V,生成单个键值对的对象类型{ [P in K]: V };
  3. 通过MergeUnion将所有单个键值对对象合并为完整的目标对象类型。

用原示例测试,现在可以得到正确的推断结果:

const x = Object.fromEntries(
  [['a', 1], ['b', 2], ['c', 'foo']] as (['a' | 'b', number] | ['c', string])[]
);
// 正确推断结果:typeof x = { a: number; b: number; c: string; }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 00:10:21