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

TypeScript中如何基于keyof预定义类型自动推断Map的value类型?

解决方案

你需要对原生Map类型做扩展,通过重载get、set方法绑定单个key和对应value的类型关系,具体实现如下:

第一步:定义扩展的Map类型

// 扩展Map接口,重载get和set方法实现键值类型绑定
interface EntitiesMapInstance extends Map<keyof EntitiesMap, Array<EntitiesMap[keyof EntitiesMap]>> {
  get<T extends keyof EntitiesMap>(key: T): Array<EntitiesMap[T]> | undefined
  set<T extends keyof EntitiesMap>(key: T, value: Array<EntitiesMap[T]>): this
}

第二步:替换类中属性的类型定义

将Household类中的inhabitantsMap类型替换为上面定义的EntitiesMapInstance,初始化时加类型断言即可:

class Household {
    inhabitantsObject: { [K in keyof EntitiesMap]?: EntitiesMap[K][] } = {}
    // 替换为扩展后的Map类型,初始化用as断言
    inhabitantsMap: EntitiesMapInstance = new Map() as EntitiesMapInstance

    getInhabitantsFromObj<T extends keyof EntitiesMap>(type: T) {
        return this.inhabitantsObject[type]
    }
    getInhabitantsFromMap<T extends keyof EntitiesMap>(type: T) {
        return this.inhabitantsMap.get(type)
    }
}

效果验证

修改完成后,返回值会自动推断为对应类型:

  • house.getInhabitantsFromMap('person') 自动推断为 Person[] | undefined
  • house.getInhabitantsFromMap('pet') 自动推断为 Pet[] | undefined
    同时调用set方法时也会有类型校验:比如给person键赋值Pet类型的数组会直接抛出类型错误。

原错误原因说明

原生Map<K, V>的两个泛型参数是「所有允许的key的联合类型」和「所有允许的value的联合类型」,本身不支持单个key和对应value的绑定,所以你之前直接写Map<keyof EntitiesMap, EntitiesMap[K]>会因为找不到K的作用域报错,就算能编译通过,get返回值也只会是所有value的联合类型,无法按传入的key自动缩小范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 11:06:02