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

如何为TypeScript中键值类型各异的Map添加精确类型定义?

为键值类型一一对应的Map实现自动类型推断

问题背景

我有一个Map,每个键对应不同类型的值,示例代码如下:

const m = new Map()

map.set(LE_CONST_NAMES, {names: ['jhon', 'pietro']})
map.set(LE_CONST_MAMA, ['unbelievable', 'yes', {who: 'are'}])
map.set(LE_CONST_OTHER, {status: 'no status'})

这些值的类型各不相同,当前取值时必须手动添加类型断言:

type Name = {names: string[]}
type Status = {status: 'no status' | 'maybe status'}

const names = map.get(LE_CONST_NAMES) as Name
const theOthers = map.get(LE_CONST_OTHER) as Status

我尝试过给Map指定联合类型值:

const m = new Map<string, Name | Status | Mama | AllTheOther40SOmethingTypes>()

但这样get返回的仍是联合类型,无法自动推断对应键的具体类型,必须手动断言。我希望自定义Map类型,让调用get时能自动识别对应类型,比如:

const names = map.get(LE_CONST_NAMES) // 自动识别为Name类型
const theOthers = map.get(LE_CONST_OTHER) // 自动识别为Status类型

解决方案

1. 定义键值映射关系

首先把所有常量键与对应值的类型整理成一个映射类型,明确每个键对应的值类型:

// 先定义各个值的具体类型
type Name = { names: string[] };
type Mama = (string | { who: string })[];
type Status = { status: 'no status' | 'maybe status' };

// 定义键到值的映射,把所有40多个键值对都补充在这里
type MapKeyToValue = {
  [LE_CONST_NAMES]: Name;
  [LE_CONST_MAMA]: Mama;
  [LE_CONST_OTHER]: Status;
};

2. 自定义带类型推断的Map接口

基于原生Map类型,重写get方法,让它根据传入的键自动返回对应类型:

type TypedMap = Omit<Map<keyof MapKeyToValue, MapKeyToValue[keyof MapKeyToValue]>, 'get'> & {
  get: <Key extends keyof MapKeyToValue>(key: Key) => MapKeyToValue[Key] | undefined;
};

3. 创建带类型约束的Map实例

创建Map时断言为自定义的TypedMap类型,后续的set和get操作都会自动做类型校验和推断:

const m = new Map() as TypedMap;

// 设置值时会校验类型,不符合会报错
m.set(LE_CONST_NAMES, { names: ['jhon', 'pietro'] });
m.set(LE_CONST_MAMA, ['unbelievable', 'yes', { who: 'are' }]);
m.set(LE_CONST_OTHER, { status: 'maybe status' });

// 取值自动推断类型,无需手动断言
const names = m.get(LE_CONST_NAMES); // 类型为 Name | undefined
const mama = m.get(LE_CONST_MAMA); // 类型为 Mama | undefined
const status = m.get(LE_CONST_OTHER); // 类型为 Status | undefined

可选:实现严格类型(无undefined)

如果能保证所有键都会被提前初始化,不需要处理undefined的情况,可以修改自定义Map类型:

type StrictTypedMap = Omit<Map<keyof MapKeyToValue, MapKeyToValue[keyof MapKeyToValue]>, 'get'> & {
  get: <Key extends keyof MapKeyToValue>(key: Key) => MapKeyToValue[Key];
};

// 初始化时传入所有键值对,确保无缺失
const m = new Map([
  [LE_CONST_NAMES, { names: ['jhon', 'pietro'] }],
  [LE_CONST_MAMA, ['unbelievable', 'yes', { who: 'are' }]],
  [LE_CONST_OTHER, { status: 'no status' }],
]) as StrictTypedMap;

const names = m.get(LE_CONST_NAMES); // 类型直接为 Name

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 20:45:48