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

如何将多个泛型TypeScript列表合并为联合类型的新列表?

实现类型安全的泛型List合并方法

需求说明

我需要给现有的泛型List<T>类添加一个静态merge方法,实现以下功能:

  • 接收任意数量的List实例作为参数
  • 将所有输入列表的项合并到一个新的List实例中
  • 返回的新列表类型必须是输入列表项类型的联合类型,完全避免any类型,保证类型安全

比如合并List<string>和List<number>后,返回的实例应该是List<string | number>类型。

现有List类代码

class List<T> {
    private items: T[];

    constructor() {
        this.items = [];
    }

    push(item: T): void {
        this.items.push(item);
    }

    getItems(): T[] {
        return this.items;
    }
}

当前问题

最初的merge方法用any类型定义,无法正确推断返回的联合类型:

class List<T> {
    // ...现有代码...

    static merge(...lists: List<any>[]): List<any> {
        // TODO: 实现逻辑
    }
}

我尝试过的实现也没能解决类型推断问题,返回的是List<any>:

static merge<T extends any[]>(...lists: { getItems: () => any }[]): List<T[number]> {
    const mergedList = new List<T[number]>();
    
    lists.forEach(list => {
        list.getItems().forEach(item => mergedList.push(item));
    });
    
    return mergedList;
}

解决方案

要实现类型安全的合并,我们需要通过泛型元组捕获输入类型,再用辅助类型提取每个列表的项类型,最终组成联合类型。

完整实现代码

// 辅助类型:从List实例中提取其项的类型
type ExtractItemType<L> = L extends List<infer U> ? U : never;

class List<T> {
    private items: T[];

    constructor() {
        this.items = [];
    }

    push(item: T): void {
        this.items.push(item);
    }

    getItems(): T[] {
        return this.items;
    }

    // 类型安全的merge静态方法
    static merge<T extends List<any>[]>(...lists: T): List<ExtractItemType<T[number]>> {
        // 创建新的合并列表,类型为提取出的联合类型
        const mergedList = new List<ExtractItemType<T[number]>>();
        
        // 遍历所有输入列表,合并项
        lists.forEach(list => {
            list.getItems().forEach(item => mergedList.push(item));
        });
        
        return mergedList;
    }
}

验证示例

const stringList = new List<string>();
stringList.push("hello");

const numberList = new List<number>();
numberList.push(123);

// mergedList的类型会被正确推断为List<string | number>
const mergedList = List.merge(stringList, numberList);

// 可以正常添加string或number类型的项
mergedList.push("world");
mergedList.push(456);

// 尝试添加其他类型会触发TypeScript报错(比如boolean)
// mergedList.push(true); // 类型“boolean”的参数不能赋给类型“string | number”的参数

原理说明

  1. 泛型元组T:T extends List<any>[]让TypeScript捕获所有输入List实例的类型组成的元组(比如输入List<string>和List<number>时,T就是[List<string>, List<number>])。
  2. T[number]:将元组类型转换为联合类型,即List<string> | List<number>。
  3. ExtractItemType:通过条件类型的infer关键字,从每个List类型中提取其内部的项类型,最终得到string | number。

这样就能保证返回的List实例类型完全基于输入列表的类型,实现类型安全的合并。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:05:43