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

TypeScript中泛型关联类型在switch语句的类型收窄实现

问题分析与解决方案

你的问题核心是:当参数类型为MyType<keyof MapType>时,TypeScript无法自动关联type和value的类型关系,导致switch语句无法收窄value的类型。这是因为MyType<keyof MapType>等价于MyType<EnumType.Type1> | MyType<EnumType.Type2> | MyType<EnumType.Type3>,但此时泛型参数是整个联合类型,而非单个枚举成员,类型关联信息被抹平了。

不用as断言的话,有两种可行方案:

方案一:将函数改为泛型函数

让函数参数保留泛型约束,TypeScript就能跟踪type和value的关联关系:

enum EnumType {
  Type1 = "Type 1",
  Type2 = "Type 2",
  Type3 = "Type 3",
}

export type MapType = {
  [EnumType.Type1]: string[];
  [EnumType.Type2]: number[];
  [EnumType.Type3]: boolean[];
};

interface MyType<Type extends keyof MapType> {
  id: string;
  type: Type;
  value: MapType[Type];
}

// 改为泛型函数
const narrowByType = <T extends keyof MapType>(obj: MyType<T>) => {
  switch (obj.type) {
    case EnumType.Type1:
      const value = obj.value; // 类型自动收窄为string[]
      break;
    case EnumType.Type2:
      const numValue = obj.value; // 类型自动收窄为number[]
      break;
    case EnumType.Type3:
      const boolValue = obj.value; // 类型自动收窄为boolean[]
      break;
  }
};

方案二:将MyType定义为判别式联合类型

直接写出每个枚举成员对应的类型,让type作为判别式,TypeScript会自动在switch中收窄类型:

enum EnumType {
  Type1 = "Type 1",
  Type2 = "Type 2",
  Type3 = "Type 3",
}

// 直接定义判别式联合类型
type MyType = 
  | { id: string; type: EnumType.Type1; value: string[] }
  | { id: string; type: EnumType.Type2; value: number[] }
  | { id: string; type: EnumType.Type3; value: boolean[] };

const narrowByType = (obj: MyType) => {
  switch (obj.type) {
    case EnumType.Type1:
      const value = obj.value; // 类型自动收窄为string[]
      break;
    case EnumType.Type2:
      const numValue = obj.value; // 类型自动收窄为number[]
      break;
    case EnumType.Type3:
      const boolValue = obj.value; // 类型自动收窄为boolean[]
      break;
  }
};

两种方案都不需要类型断言,就能实现你预期的类型收窄效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 02:36:16