kmw*_*ter 5 javascript instantiation implicit flowtype redux
我现在在 Redux 中的 combineReducers 上收到以下错误。
缺少类型注释A。A是在函数类型 [1] 中声明的类型参数,并在调用combineReducers[2] 时隐式实例化。
代码如下所示,但出现在我所有使用 combineReducers 的减速器中。
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<*>),
});
Run Code Online (Sandbox Code Playgroud)
我相信这是因为 Redux flow-types 中的这种类型定义
declare export function combineReducers<O: Object, A>(reducers: O):
CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;
Run Code Online (Sandbox Code Playgroud)
我相信这与 Flow 的发布有关,版本 0.85.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<*>),
});
Run Code Online (Sandbox Code Playgroud)
我这样做是因为我看到 Redux 文档中的函数定义是
combineReducers<O: Object, A>
Run Code Online (Sandbox Code Playgroud)
但是我不完全理解为什么会这样,或者不知道这实际上是正确的解决方案还是没有意义,我只是很幸运。我曾尝试在 Google 上搜索 IMPLICIT INSTANTIATIONS,但我什么也没找到。我准备好了这篇文章,但我仍然不知道调用的返回类型应该基于什么进行注释
combineReducers<O: Object, A>
Run Code Online (Sandbox Code Playgroud)
长话短说
替换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,调用每个成员(我们希望它们是函数)并返回类型。查看文档,这是非常强大的东西。
这部分:<S>(r: Reducer<S, any>) => S可能被称为extract function type。用人类的话来说,可以说是 -> reducer 可能返回任何类型,对吧?因此,让我们将reducer返回的状态放入generic中<S>,然后将返回的类型放入此generic中。我需要超过 1 天的时间来了解它是如何工作的,希望在你的情况下它会更快。:)
所以最后:combineReducer<S, A>- 给定状态S(这是对象,每个成员都是减速器)和操作A返回一个对象,该对象的成员是每次调用成员的结果类型S。
所以,你的status减速函数 - 可以更好地描述为
Reducer<boolean, Action> //accepts boolean, Action args & return boolean
Run Code Online (Sandbox Code Playgroud)
我们可以将状态定义为:
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;
}
}),
});
Run Code Online (Sandbox Code Playgroud)
要检查输入是否正确,您可以导入您的减速器,并转换表达式:
const checkState = reducer({status: true}, {type: 'START_SESSION'});
(checkState.status: number); // ERROR
(checkState.status: boolean); // CORRECT
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你。