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

如何实现异构数组中match函数回调的类型收窄

让match函数的回调参数自动收窄到对应case类型

你当前的match函数因为泛型V是统一的顶层类型,导致每个回调的参数只能是V,没办法自动收窄到具体的case值类型。要实现你想要的类型收窄效果,需要调整类型定义和函数的泛型约束,让TypeScript能精确推导每个case的匹配值类型。

修改后的类型与函数实现

// 单个case的类型定义,K是匹配值的类型
type CaseItem<K> = 
  | [K, (value: K) => void]
  | [K[], (value: K) => void];

// 定义match函数的泛型,Cases是所有case的联合类型
const match = <Cases extends CaseItem<any>[]>(
  value: Cases[number] extends CaseItem<infer K> ? K : never,
  cases: readonly [...Cases]
) => {
  for (const [key, func] of cases) {
    if (Array.isArray(key)) {
      if ((key as unknown[]).includes(value)) {
        return func(value as Cases[number] extends CaseItem<infer K> ? K : never);
      }
    } else {
      if (key === value) {
        return func(value);
      }
    }
  }
};

关键说明

  • 精确绑定case类型:CaseItem<K>让每个case单独绑定自己的匹配值类型K,不管是单个值还是数组,回调参数都对应K类型(数组场景下K会自动推导为元素的联合类型)。
  • 泛型推导约束:函数泛型Cases约束为CaseItem<any>[],通过条件类型推导出所有case匹配值的联合类型,作为value的类型约束,确保传入的value只能是case中存在的值。
  • const断言的作用:调用时必须加上as const,让TypeScript保留数组元素的字面量类型,避免自动拓宽为string这类宽泛类型,才能实现精确的类型收窄。

使用示例

const value: "something" | "other" | "thing" = "something";

match(value, [
  [
    "something",
    (v) => {
      // v的类型自动收窄为 "something"
      console.log(v.toUpperCase());
    }
  ],
  [
    ["other", "thing"],
    (v) => {
      // v的类型自动收窄为 "other" | "thing"
      if (v === "other") {
        console.log("it's other");
      } else {
        console.log("it's thing");
      }
    }
  ]
] as const);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 05:22:03