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

如何在泛型Map中实现键到值的类型级联?

将联合类型映射对象转为带精确类型推断的Map

要实现基于Map的精确类型推断,核心是重载Map的get方法,让它根据传入的具体键返回对应类型的值。以下是完整实现:

type Category = 'A' | 'B' | 'C';

interface DataRecord<TCategory extends string = string> {
    category: TCategory;
    data: Record<string, string>;
}

// 重载Map的get方法,实现精确类型推断
type DataRecordGroups = Map<Category, DataRecord<Category>[]> & {
    get<K extends Category>(key: K): DataRecord<K>[] | undefined;
};

// 初始化Map,TypeScript会自动校验条目类型
const groups: DataRecordGroups = new Map([
    ['A', [{ category: 'A', data: { id: 'a1' } }]],
    ['B', [{ category: 'B', data: { id: 'b1' } }]],
    ['C', [{ category: 'C', data: { id: 'c1' } }]]
]);

// 验证类型推断效果
const groupA = groups.get('A'); // 类型:DataRecord<'A'>[] | undefined
if (groupA) {
    const catA = groupA[0].category; // 类型:'A'(精确字面量类型)
}

const groupB = groups.get('B'); // 类型:DataRecord<'B'>[] | undefined
if (groupB) {
    const catB = groupB[0].category; // 类型:'B'(精确字面量类型)
}

原理说明

原生Map<Category, DataRecord<Category>[]>的get方法只能返回DataRecord<'A'|'B'|'C'>[] | undefined,无法区分不同键对应的具体类型。通过:

  1. 保留基础Map的结构,确保可以使用所有Map原生方法
  2. 重载get方法,引入泛型K extends Category,让方法根据传入的键K,精确返回DataRecord<K>[] | undefined

如果需要更严格的构造校验,可以先定义精确的条目类型联合,再约束Map的构造参数:

// 定义每个键值对的精确类型
type DataRecordEntry = { [K in Category]: [K, DataRecord<K>[]] }[Category];

// 同样重载get方法的Map类型
type DataRecordGroups = Map<Category, DataRecord<Category>[]> & {
    get<K extends Category>(key: K): DataRecord<K>[] | undefined;
};

// 构造时传入的数组必须符合DataRecordEntry[]类型
const groups: DataRecordGroups = new Map<DataRecordEntry>([
    ['A', [{ category: 'A', data: {} }]],
    // 如果传入['A', [{ category: 'B', data: {} }]]会直接报错
]);

这样能确保初始化的Map条目完全符合类型要求,避免出现键值不匹配的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 23:12:17