TypeScript如何根据参数确定函数的返回类型?
TypeScript根据函数参数确定返回类型的问题解决
我需要实现一个函数getPropsForComponentKey,要求根据传入的ComponentKey枚举值返回对应的props类型:传入ComponentKey.A时返回AProps,传入ComponentKey.B时返回BProps,同时希望通过控制流分析避免返回类型不兼容的值。
尝试用泛型T结合索引类型PropTypesForComponentKey[T]定义返回类型,但编译器报错,提示AProps无法赋值给PropTypesForComponentKey[T]。
原始代码示例
type AProps = { value: number; } type BProps = { description: string; } enum ComponentKey { A = 'A', B = 'B', } type PropTypesForComponentKey = { [ComponentKey.A]: AProps; [ComponentKey.B]: BProps; } // 该对象强制约束了key与value类型的映射关系 const propsForComponentKey: PropTypesForComponentKey = { [ComponentKey.A]: { value: 3 }, [ComponentKey.B]: { description: 'foo' }, } // 使用'A'作为索引时,我们知道aProp是AProps类型 const aProp = propsForComponentKey['A']; // 如何约束该函数的返回类型? function getPropsForComponentKey<T extends ComponentKey>(componentKey: T): null | PropTypesForComponentKey[T] { switch(componentKey) { case ComponentKey.A: return { value: 3 } as AProps; case ComponentKey.B: return { description: 'foo' }; } return null; }
解决方案
方法1:使用函数重载
通过函数重载明确指定每个参数对应的返回类型,让TypeScript的控制流分析精准生效:
// 重载签名:定义参数与返回类型的映射 function getPropsForComponentKey(componentKey: ComponentKey.A): null | AProps; function getPropsForComponentKey(componentKey: ComponentKey.B): null | BProps; // 实现签名:使用联合类型兼容所有情况 function getPropsForComponentKey(componentKey: ComponentKey): null | AProps | BProps { switch(componentKey) { case ComponentKey.A: return { value: 3 }; case ComponentKey.B: return { description: 'foo' }; } return null; } // 使用示例:类型推断正确 const propsA = getPropsForComponentKey(ComponentKey.A); // 类型为 null | AProps const propsB = getPropsForComponentKey(ComponentKey.B); // 类型为 null | BProps
方法2:优化泛型函数的类型断言
在每个switch分支中,将返回值断言为PropTypesForComponentKey[T],明确告诉编译器当前分支的返回值符合泛型对应的类型:
function getPropsForComponentKey<T extends ComponentKey>(componentKey: T): null | PropTypesForComponentKey[T] { switch(componentKey) { case ComponentKey.A: return { value: 3 } as PropTypesForComponentKey[T]; case ComponentKey.B: return { description: 'foo' } as PropTypesForComponentKey[T]; } return null; } // 使用示例:类型推断正确 const propsA = getPropsForComponentKey(ComponentKey.A); // 类型为 null | AProps const propsB = getPropsForComponentKey(ComponentKey.B); // 类型为 null | BProps
两种方法都能实现需求:函数调用时根据传入的参数自动推断返回类型,同时确保返回值的类型兼容性。
内容的提问来源于stack exchange,提问作者Keith Williams
相关产品推荐
相关产品推荐

