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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:11:07