基于枚举参数的二维键值组合类型校验实现问题
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
相关产品推荐
相关产品推荐

