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

基于枚举参数的二维键值组合类型校验实现问题

TypeScript枚举组合与值校验问题解决

问题背景

现有两个枚举类型A、B,以及一个两层级的键值存储MODEL,定义如下:

enum A { a, b }
enum B { c, d }

const MODEL: { [key in A]?: { [key in B]?: string } } = {
  [A.a]: {
    [B.c]: "test"
  }
}

需要创建一个方法,实现以下校验逻辑:

  • 仅允许调用时传入MODEL中存在的枚举组合(A+B的键对)
  • 传入的值必须与MODEL中对应组合的取值完全匹配

预期调用效果:

myMethod(A.a, B.c, "test") // 无错误,组合及值均合法
myMethod(A.a, B.d, "test") // 报错,该枚举组合不存在于MODEL
myMethod(A.a, B.c, "result") // 报错,值与MODEL定义不符

尝试编写的方法类型签名出现报错:Type 'B' cannot be used to index type <big object type redacted>,需要解决该问题并实现预期校验。

解决方案

方案一:处理可选类型并约束泛型范围

原报错原因在于(typeof MODEL)[E1]是可选类型(可能为undefined),且泛型约束过于宽泛,导致TypeScript无法确认E2是有效索引。通过NonNullable处理可选类型,并缩小泛型约束范围即可解决:

const myMethod = <E1 extends keyof typeof MODEL, E2 extends keyof NonNullable<(typeof MODEL)[E1]>>(
  arg1: E1,
  arg2: E2,
  value: NonNullable<(typeof MODEL)[E1]>[E2]
) => {
  // 方法逻辑实现
};

方案二:基于精确推导类型生成合法组合

如果希望更严格地约束参数,可先让TypeScript精确推导MODEL的类型,再生成所有合法的参数组合类型:

enum A { a, b }
enum B { c, d }

// 用as const让TypeScript保留MODEL的精确键值类型
const MODEL = {
  [A.a]: {
    [B.c]: "test"
  }
} as const;

// 提取所有合法的[枚举A, 枚举B, 对应值]组合类型
type ValidCombination = {
  [E1 in keyof typeof MODEL]: {
    [E2 in keyof typeof MODEL[E1]]: [E1, E2, typeof MODEL[E1][E2]]
  }[keyof typeof MODEL[E1]]
}[keyof typeof MODEL];

// 方法参数直接使用合法组合类型约束
const myMethod = (...args: ValidCombination) => {
  // 方法逻辑实现
};

验证效果

两种方案均能实现预期校验:

  • 合法组合与值:myMethod(A.a, B.c, "test") 正常通过
  • 不存在的枚举组合:myMethod(A.a, B.d, "test") 触发类型报错
  • 不匹配的值:myMethod(A.a, B.c, "result") 触发类型报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:45:55