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

TypeScript:如何去除对象根键合并嵌套对象并转联合类型为交叉类型?

解决TypeScript合并多语言对象返回交叉类型的问题

你的merge函数当前返回的是各语言对象的联合类型,要改成返回交叉类型,可以通过自定义工具类型结合泛型调整来实现:

步骤1:定义联合转交叉的工具类型

TypeScript本身没有内置的联合转交叉类型,但可以利用条件类型的逆变特性实现:

type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

步骤2:修改merge函数的泛型与返回类型

调整函数的泛型约束和返回类型,让它返回所有语言对象的交叉类型,同时修正内部的类型断言:

type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

function merge<A extends Record<string, object>>(a: A): UnionToIntersection<A[keyof A]> {
  let ret = {} as UnionToIntersection<A[keyof A]>;
  // 注意:Object.keys的遍历顺序不固定,若需要默认语言优先,建议显式指定默认语言先合并
  Object.values(a).forEach(obj => {
    ret = { ...ret, ...obj };
  });
  return ret;
}

const o = { en: { a: 1 }, de: { b: 2, c: "3" } };
const r = merge(o);
// 此时 r 的类型为 {a: 1} & {b: 2, c: "3"}

补充说明

  • 原函数中用Object.keys遍历后取a[key],可以直接换成Object.values(a)更简洁。
  • 实际场景中如果需要默认语言(比如en)的属性覆盖其他语言的同名属性,建议先合并默认语言对象,再合并其他语言:
    function mergeWithDefault<A extends Record<string, object>, D extends keyof A>(a: A, defaultLang: D): UnionToIntersection<A[keyof A]> {
      let ret = { ...a[defaultLang] } as UnionToIntersection<A[keyof A]>;
      Object.entries(a).forEach(([lang, obj]) => {
        if (lang !== defaultLang) {
          ret = { ...ret, ...obj };
        }
      });
      return ret;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 05:20:24