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

如何基于Type<Param>创建类型,实现对象类型合并?

问题描述

我定义了以下类型与变量:

type ToConcat<M> = {}

const mid1:ToConcat<{foo:'bar'}> = {}

const mid2:ToConcat<{john:'doe'}> = {}

我想要实现:

const finalObject = [mid1, mid2, myAttempted] 

其中myAttempted的类型是mid1和mid2对应类型的合并结果,也就是:

{
 foo: 'bar',
 john:'doe'
}

我尝试了下面的代码但无法正常运行:

type Mid<L> = {
    locals: L
}

type Fi<M extends Mid<any>[]> = {
        [key in keyof M[number]['locals']]: M[number]['locals'][key]
}

const mi1:Mid<{foo:'bar'}> = {
    locals: {foo: "bar"}
}
const mi2:Mid<{john:'doe'}> = {
    locals: {john: "doe"}
}

type P<R extends Mid<any>[]> = [...R, Fi<R>]

const g:P<[typeof mi1, typeof mi2]> = [mi1, mi2, {
    locals: {
        // 此处无法得到类型提示与校验
    }
}]

我的最终需求是:仅需声明mid1、mid2为对象,即可得到对应的合并类型。

解决方案

核心问题分析

你之前的Fi类型使用M[number]['locals']会得到联合类型的键,但值会变成所有对应类型的联合,并且无法正确合并成交叉类型,导致类型提示失效。我们需要先从ToConcat<M>中提取内部类型,再将这些类型合并为交叉类型,最终生成目标对象类型。

实现代码

// 从ToConcat<M>中提取内部泛型类型
type ExtractToConcatType<T> = T extends ToConcat<infer U> ? U : never;

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

// 合并数组中所有ToConcat对应的内部类型
type MergeToConcat<T extends ToConcat<any>[]> = UnionToIntersection<ExtractToConcatType<T[number]>>;

// 定义最终数组的类型结构:原对象 + 合并后的对象
type FinalArray<T extends ToConcat<any>[]> = [...T, MergeToConcat<T>];

// 你的原始类型与变量定义
type ToConcat<M> = {}
const mid1: ToConcat<{ foo: 'bar' }> = {}
const mid2: ToConcat<{ john: 'doe' }> = {}

// 使用示例:手动指定类型
const finalObject: FinalArray<[typeof mid1, typeof mid2]> = [mid1, mid2, {
  foo: 'bar',
  john: 'doe'
}]

简化使用:自动推导类型

如果不想手动指定泛型参数,可以写一个辅助函数自动推导:

function createFinalArray<T extends ToConcat<any>[]>(...args: [...T, MergeToConcat<T>]) {
  return args;
}

// 直接传入参数即可,自动推导合并类型
const finalObject = createFinalArray(mid1, mid2, {
  foo: 'bar',
  john: 'doe'
});

代码说明

  1. ExtractToConcatType:通过条件类型的infer关键字,精准提取ToConcat包裹的内部类型。
  2. UnionToIntersection:TypeScript经典工具类型,将联合类型转为交叉类型,实现多个对象类型的合并。
  3. MergeToConcat:基于前两个工具类型,得到所有ToConcat对象对应的内部类型的合并结果。
  4. FinalArray:构造数组类型,确保前两个元素是原ToConcat对象,最后一个元素是合并后的类型,提供完整的类型提示与校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 07:03:21