【问题标题】:Typescript types for a hook that returns a piece of the Redux state返回 Redux 状态的钩子的 Typescript 类型
【发布时间】:2020-12-03 15:20:30
【问题描述】:

我有一个名为 useReduxState 的钩子,我用它来从 Redux 中检索一段状态:

const STATE_A = useReduxState("STATE_A");

我在向其中添加 Typescript 时遇到了麻烦。

这些是我正在使用的类型:

type TYPE_A = {
  fooA: string,
  barA: string,
}

type TYPE_B = {
  fooB: string,
  barB: string
}

interface REDUX_STATE {
  STATE_A: TYPE_A,
  STATE_B: TYPE_B,
}

这是钩子的代码(它使用来自react-redux 包的useSelector 钩子);

function useReduxState(STATE_NAME: REDUX_STATE_KEYS): REDUX_STATE_VALUES {
  
  const STATE = useSelector((state: REDUX_STATE) : REDUX_STATE_VALUES => state[STATE_NAME]);
  return STATE;

}

我的目标是能够写出如下内容:

const { fooA, barA } = useReduxState("STATE_A");

我希望 Typescript 知道我可以访问这两个属性 fooA and barA,因为它们存在于 TYPE_A 中,这是 STATE_A 的类型。

但我遇到了这些错误:

Property 'fooA' does not exist on type 'REDUX_STATE_VALUES'.ts(2339)
Property 'barA' does not exist on type 'REDUX_STATE_VALUES'.ts(2339)

这里是REDUX_STATE_VALUES的类型

看起来是正确的,但我想让 Typescript 知道当我将"STATE_A" 作为参数传递时,返回类型应该是TYPE_A,所以我可以访问它的属性fooA and barA"STATE_B" 及其类型反之亦然。

我怎样才能做到这一点?在这种情况下我应该使用泛型来获得这种行为吗?

【问题讨论】:

    标签: reactjs typescript redux typescript-typings


    【解决方案1】:

    您是否考虑过使用 TypeScript 接口来映射对象 TYPE_A 和 TYPE_B。

    export interface TypeA {
       fooA: string;
       barA: string
    }
    
    export interface TypeB {
        fooB:string;
        barB: string
    }
    

    在你的 ReduxState 接口文件中导入 TypeA 和 TypeB 接口

    export interface ReduxState {
       Type_A: TypeA;
       Type_B: TypeB;
    

    }

    【讨论】:

    • 谢谢,但这不是我想要的答案。
    【解决方案2】:

    您需要一个泛型,以便对您的函数的每次调用都将确定它正在访问哪个字段:

    function useReduxState<K extends keyof REDUX_STATE>(STATE_NAME: K): REDUX_STATE[K] {
    

    参数将是一个keyof REDUX_STATE,返回类型将是相应的值,所以当你被传递一个特定的字符串时,它会找出正确的返回类型。

    您还需要删除函数上的显式返回注释,它会从用法中推断出正确的类型,并且您需要比 REDUX_STATE_VALUES 更具体

    useSelector((state: REDUX_STATE) => state[STATE_NAME])
    

    【讨论】:

    • 非常感谢您的回答。真的帮了我大忙。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多