缺少在函数类型中声明的类型参数的类型注释,该类型参数是在调用CombineReducers时隐式实例化的

时间:2019-01-28 03:43:52

标签: javascript redux instantiation flowtype implicit

我现在在Redux中的CombineReducers上遇到以下错误。

A缺少类型注释。 A是在函数类型[1]中声明的类型参数,并且在调用combineReducers [2]时隐式实例化。

代码如下所示,但是我所有使用CombineReducers的reducer都出现了。

export default combineReducers({
  status: ((state: boolean = true, action: Action) => {
    switch (action.type) {
      case 'START_SESSION':
      case 'REFRESH_AUTH_SUCCEEDED':
      case 'SIGN_IN_FAILED':
      case 'SIGN_OUT':
        return false;
      default:
        return state;
    }
  }: Reducer<*>),
});

我相信是由于Redux流类型中的这种类型定义


declare export function combineReducers<O: Object, A>(reducers: O): 
       CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;

我认为这与Flow的发布(版本5.05.0)有关,该版本引入了一些与“隐式实例化”有关的内容。

我阅读了FLow自己的Sam Goldman撰写的有关Medium的文章,这就是我得出这一结论的方式。 https://medium.com/flow-type/asking-for-required-annotations-64d4f9c1edf8

通过执行以下操作,我得以解决该错误,这是我尝试实现类似解决方案文章“为函数调用提供显式类型实参”的尝试。

export default combineReducers<Object, Action>({
  status: ((state: boolean = true, action: Action) => {
    switch (action.type) {
      case 'START_SESSION':
      case 'REFRESH_AUTH_SUCCEEDED':
      case 'SIGN_IN_FAILED':
      case 'SIGN_OUT':
        return false;
      default:
        return state;
    }
  }: Reducer<*>),
});

之所以这样做,是因为我看到Redux文档中的函数定义是

combineReducers<O: Object, A>

但是我不完全理解为什么这样做还是不知道这实际上是正确的解决方案还是没有道理,我很幸运。我曾尝试在Google上搜索隐式实例,但我什么都没找到。我已经准备好这篇文章,但我仍然不完全知道应该基于

将该调用的返回类型标注为哪种类型。
combineReducers<O: Object, A>

1 个答案:

答案 0 :(得分:1)

TL; DR

用对象替换Object,其中键为-状态键,值为化简器定义:{status: Reducer<boolean, Action>}

所以您会得到:

combineReducers<{status: Reducer<boolean, Action>}, Action>(...)

好答案。

Reducer<S, any>-reducer是一个纯函数,它接受当前状态和操作并返回新状态。就是这样,非常简单。这样,它在flow-typed中得到了准确的描述:

declare export type Reducer<S, A> = (state: S | void, action: A) => S

$ObjMap<O, <S>(r: Reducer<S, any>) => S>-这更复杂,映射到给定的对象O,调用每个成员(我们希望它们是函数)并返回类型。查看doc,这是非常强大的功能。

这部分:<S>(r: Reducer<S, any>) => S可能称为extract function type。用人类的话来说-> reducer可能返回任何类型,对吗?因此,让我们将reducer的返回状态放入通用<S>中,然后将返回的类型放入该generic中。我需要超过1天的时间来了解其工作原理,希望您的情况更快。 :)

所以最后:combineReducer<S, A>-给定状态S(这是Object,每个成员都是化简),而动作A返回一个对象,该对象的成员是每次调用成员时的结果类型S

因此,您的status减速器功能-可以更好地描述为

Reducer<boolean, Action> //accepts boolean, Action args & return boolean

我们可以将状态定义为:

type State = { status: Reducer<boolean, Action> };

然后,将状态传递给CombineReducer:

export default combineReducers<State, Action>({
    status: ((state: boolean = true, action: Action) => {
        switch (action.type) {
        case 'START_SESSION':
        case 'REFRESH_AUTH_SUCCEEDED':
        case 'SIGN_IN_FAILED':
        case 'SIGN_OUT':
            return false;
        default:
            return state;
        }
    }),
});

要检查键入是否正确,您可以导入减速器,然后cast the expressions

const checkState = reducer({status: true}, {type: 'START_SESSION'});
(checkState.status: number); // ERROR
(checkState.status: boolean); // CORRECT

希望有帮助。