-
-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Update argument type of reducer produced by combineReducers #2115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update argument type of reducer produced by combineReducers #2115
Conversation
|
tagging @gcanti and @aaronjensen |
|
Using // test_combineReducers.js in flow-typed
type State = {
a: AState,
name: string,
age: number
};
const reducer1: Reducer<State, Action> = combineReducers({
a: reducerA,
name: reducerName
// missing age reducer but no error
})
What do you mean? The root reducer is not supposed to be called "by hand" rootReducer({}, someAction); |
@gcanti See Dan Abramov's response here where he details a recommended approach to resetting the store. That would be the use case. In his case, he names it "appReducer" but it is the same idea. |
|
@nickarora note that in the linked approach declare function combineReducers<O: Object, A>(reducers: O): Reducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S> | void, A>; |
|
@gcanti I've pushed up a change that should address your type-safety concerns while still allowing state to be reset using their default initialValues -- as dan explains. |
|
@nickarora I think I may have misled you on this a little when we talked earlier. If The result of Basically, if you pass Adding declare type CombinedReducer<S, A> = (state: $Shape<S> | void, action: A) => S
declare function combineReducers<O: Object, A>(reducers: O): CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>; |
|
Sounds reasonable to me -- I'll let @gcanti weigh in before making any other changes |
|
Not sure why Beware: type O = { name: string };
const x1: $Shape<O> = undefined // <= ok
const x2: $Shape<O> = null // <= okMaybe we should exclude declare type CombinedReducer<S, A> = (state: $Shape<S> & {} | void, action: A) => S;
declare function combineReducers<O: Object, A>(reducers: O): CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;Then you can write import type { Store } from 'redux'
import { createStore, combineReducers } from 'redux'
type State = {
a: number,
b: number
};
type Action = { type: 'RESET' };
const appReducer = combineReducers({
a: (s = 1) => s,
b: (s = 2) => s
})
const reducer = (s, a) => {
if (a.type === 'RESET') {
// return appReducer(null, a) // <= error
// return appReducer(undefined, a) // <= ok
return appReducer({}, a) // <= ok
// return appReducer({ a: s.a }, a) // <= ok, partially reset the store
// return appReducer({ a: 'a string' }, a) // <= ok BUG :( see https://github.com/facebook/flow/issues/2674
}
return appReducer(s, a)
}
const store: Store<State, Action> = createStore(reducer, { a: 3, b: 4 }) |
In our case, yes.
Ah, thanks.
Agreed.
Ugh. That was already a problem though, yeah? So this wouldn't introduce a new bug afaict. Ok, so it sounds like the |
Yes, I agree, that was already a problem. It's not critical if you use the result of
I ran this change against the tests in the flow-typed repo and they are still green |
|
@gcanti @aaronjensen updated and opened a PR in the flow-typed repo as well |
|
Thanks for the fix! |
…2115) * update argument type of reducer produced by combineReducers * update Reducer type to use $Shape * define CombinedReducer type
Addresses #2114
Updates CombineReducers flow-type