TypeScript:如何根据输入正确确定函数的返回类型
TypeScript泛型与Redux Selector类型不匹配问题
类型定义
预先定义的输入输出类型:
type Input = 'foo' | 'bar' type Output = { 'foo': string 'bar': BarType }
Redux Store配置
Redux根Reducer配置:
const rootReducer = combineReducers({ bar: BarReducer, // 注:原代码此处缺失逗号,已补全 foo: FooReducer })
问题场景:useData钩子的两种实现
在useData钩子中通过Redux的useSelector获取数据,尝试了两种写法均不符合预期:
1. 使用泛型的实现(编译报错)
代码:
function useData<T extends Input>(key: T): Output[T] { const useReduxSelector = useSelector.withTypes<RootState>() const {data} = useReduxSelector(state => state[key]) return data }
编译错误信息:
Type 'string | BarType' is not assignable to type 'Output[T]'. Type 'BarType' is not assignable to type 'Output[T]'. Type 'BarType' is not assignable to type 'Account & string'. Type 'BarType' is not assignable to type 'string'.
2. 移除泛型的实现(返回联合类型不符合预期)
代码:
function useData(key: Input): Output[Input] { const useReduxSelector = useSelector.withTypes<RootState>() const {data} = useReduxSelector(state => state[key]) return data }
编译无报错,但组件调用useData时,返回类型始终是string | BarType,无法根据传入的key自动窄化为对应精确类型。
问题原因
TypeScript无法跨useSelector的回调函数边界保留泛型T的窄化信息。传入泛型T时,TypeScript只能推断state[key]的类型是RootState['foo'] | RootState['bar'],进而data的类型是string | BarType,无法自动关联到Output[T]的精确类型。
解决方案
通过类型断言明确告知TypeScriptdata的类型为Output[T],修改后的代码:
function useData<T extends Input>(key: T): Output[T] { const useReduxSelector = useSelector.withTypes<RootState>(); // 断言返回值的data属性类型为Output[T] const { data } = useReduxSelector(state => state[key]) as { data: Output[T] }; return data; }
需确保RootState的类型与Output完全对齐:RootState['foo'].data必须是string,RootState['bar'].data必须是BarType,避免类型断言带来的安全风险。
内容的提问来源于stack exchange,提问作者Trung Kiến
相关产品推荐
相关产品推荐

