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

如何实现Typescript泛型,合并接口所有子属性为可选类型?

TypeScript 泛型实现多子对象属性合并解决方案

问题根因

你之前的写法失效的核心原因是:keyof 作用于联合类型时,只会返回联合所有成员共有的属性名。在你的示例中Test[keyof Test] 是{a:string,b:string,c:string} | {a:string,b:string,d:string},所以keyof Test[keyof Test]只能拿到共有属性a | b,自然会丢失c和d。

正确实现

简洁版实现(基于联合转交叉工具)

// 联合转交叉的通用工具类型
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

// 目标泛型实现
type CombinedChildren<T extends Record<string, object>> = Partial<UnionToIntersection<T[keyof T]>>;

效果验证

export type Combined = CombinedChildren<Test>;
// 完全符合预期输出:
// {
//   a?: string;
//   b?: string;
//   c?: string;
//   d?: string;
// }

实现原理

  1. 先通过T[keyof T]拿到输入类型所有子对象的联合类型
  2. 用UnionToIntersection把联合类型转成交叉类型,聚合所有子对象的属性
  3. 最后用Partial把所有属性设为可选,即可得到预期结果

无额外工具类型的实现方案

如果不想引入UnionToIntersection,也可以用分发条件类型显式收集所有键实现,效果完全一致:

// 收集联合类型所有成员的全部键
type AllUnionKeys<U> = U extends any ? keyof U : never;

type CombinedChildren<T extends Record<string, object>> = Partial<{
  [K in AllUnionKeys<T[keyof T]>]: T[keyof T] extends Record<K, infer V> ? V : never
}>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 04:15:03