TypeScript中如何将枚举参数映射为对应返回类型?
解决TypeScript枚举参数对应返回值类型的问题
问题原因
你当前的代码中,TypeScript无法在条件分支里将泛型T精确收窄到Type.TypeOne或Type.TypeTwo,导致它把{ [Type.TypeOne]: T1; [Type.TypeTwo]: T2 }[T]错误推断为T1 & T2(交叉类型),而非预期的对应索引类型,最终引发类型不匹配报错。
解决方案
方案1:使用函数重载
这是最直观的实现方式,通过重载签名明确枚举参数与返回值的对应关系:
type T1 = { name: string } type T2 = { age: number } enum Type { TypeOne, TypeTwo } // 定义重载签名,明确参数与返回值的类型映射 function get(type: Type.TypeOne): T1; function get(type: Type.TypeTwo): T2; // 实现签名,处理实际逻辑 function get(type: Type): T1 | T2 { return type === Type.TypeOne ? { name: 'Brian' } : { age: 42 } } // 调用示例 const res1 = get(Type.TypeOne); // 类型为T1 const res2 = get(Type.TypeTwo); // 类型为T2
方案2:泛型+类型断言保留映射类型
如果想保留原有的映射类型结构,可以通过类型断言告诉TypeScript分支返回值的具体类型:
type T1 = { name: string } type T2 = { age: number } enum Type { TypeOne, TypeTwo } // 定义枚举到类型的映射 type TypeMap = { [Type.TypeOne]: T1 [Type.TypeTwo]: T2 } const get = <T extends Type>(type: T): TypeMap[T] => { if (type === Type.TypeOne) { // 断言当前分支返回值匹配TypeMap[T] return { name: 'Brian' } as TypeMap[T] } else { return { age: 42 } as TypeMap[T] } } // 调用示例 const res1 = get(Type.TypeOne); // 类型为T1 const res2 = get(Type.TypeTwo); // 类型为T2
方案3:对象映射实现类型自动推断
通过对象存储枚举对应的处理函数,让TypeScript自动推断返回值类型,扩展性更好:
type T1 = { name: string } type T2 = { age: number } enum Type { TypeOne, TypeTwo } // 定义每个枚举对应的处理函数 const typeHandlers = { [Type.TypeOne]: () => ({ name: 'Brian' }), [Type.TypeTwo]: () => ({ age: 42 }), } satisfies Record<Type, () => T1 | T2>; const get = <T extends Type>(type: T): ReturnType<typeof typeHandlers[T]> => { return typeHandlers[type](); } // 调用示例 const res1 = get(Type.TypeOne); // 类型为T1 const res2 = get(Type.TypeTwo); // 类型为T2
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

