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

如何让TypeScript接受Map中的联合类型?

问题分析:TypeScript联合类型Map赋值报错原因及解决办法

问题代码

type DataKey = string
type DataValue = {type:'A',a:string} | {type:'B',b:number}
type ObjType = {data: Map<DataKey,DataValue>}

const obj: ObjType = {data: new Map}

fpShallowMerge<ObjType>({
    data: fpMapSet('b', {
        type: 'B',
        b: 55,
    })
})

报错信息

Type '(map: nil | Map<string, { type: "B"; b: number; }>) => Map<string, { type: "B"; b: number; }>' is not assignable to type 'Map<string, DataValue> | ((args_0: Map<string, DataValue>, args_1: "data") => Map<string, DataValue>) | undefined'.
  Type '(map: nil | Map<string, { type: "B"; b: number; }>) => Map<string, { type: "B"; b: number; }>' is not assignable to type '(args_0: Map<string, DataValue>, args_1: "data") => Map<string, DataValue>'.
    Types of parameters 'map' and 'args_0' are incompatible.
      Type 'Map<string, DataValue>' is not assignable to type 'Map<string, { type: "B"; b: number; }>'.
        Type 'DataValue' is not assignable to type '{ type: "B"; b: number; }'.
          Property 'b' is missing in type '{ type: "A"; a: string; }' but required in type '{ type: "B"; b: number; }'.(2322)

报错原因

核心问题出在TypeScript对Map泛型的类型兼容性检查和fpMapSet的自动类型推断逻辑:

  1. fpMapSet('b', {type:'B', b:55})返回的函数,TypeScript默认推断它只能接收Map<string, {type:'B', b:number}>类型的参数——因为传入的值是B类型,TS认为这个Map只能存储B类型元素。
  2. 但fpShallowMerge要求data对应的函数参数是Map<string, DataValue>,这个Map允许同时存在A和B类型的元素。
  3. 当尝试把期望接收纯B类型Map的函数,赋值给需要接收混合A/B类型Map的位置时,TS会检查:Map<string, DataValue>包含A类型元素,而A类型没有b属性,不符合Map<string, B>的元素要求,因此判定类型不兼容,抛出错误。

解决办法

1. 显式指定fpMapSet的泛型类型

直接告诉TS,这个操作针对的是DataValue类型的Map:

fpShallowMerge<ObjType>({
    data: fpMapSet<DataKey, DataValue>('b', {
        type: 'B',
        b: 55,
    })
})

2. 调整fpMapSet的泛型定义(自定义函数场景)

让函数支持往包含联合类型的Map中添加元素,修改类型定义:

function fpMapSet<K, V>(key: K, value: V) {
  return <T extends V>(map: Map<K, T> | null | undefined) => {
    const newMap = new Map(map);
    newMap.set(key, value as T);
    return newMap;
  };
}

3. 类型断言(不推荐)

如果确定类型安全,可以用断言跳过检查,但会失去TS的类型保护:

fpShallowMerge<ObjType>({
    data: fpMapSet('b', {
        type: 'B',
        b: 55,
    }) as (map: Map<DataKey, DataValue>) => Map<DataKey, DataValue>
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:13:20