TypeScript definitions allow a reducer that doesn't handle all possible actions
See original GitHub issueDo you want to request a feature or report a bug?
Bug
What is the current behavior?
If the current behaviour is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar.
I’m using TypeScript and hit a situation where I managed to register my main reducer as only receiving my specific types of actions. This is a simplified version though somehow in my real case I managed to make the reducer not even need to accept undefined for the state: https://gist.github.com/Mossop/2871372747e55e0fedea64eb649067e6.
This compiles correctly with TypeScript because TypeScript thinks I have handled all possible actions, and returned a valid state however this is incorrect. My reducer will actually receive other actions such as the INIT action that redux sends when the store is first created. When this reaches my reducer it just returns undefined and now my store is in an unexpected state.
What is the expected behavior?
Obviously I can fix this by just always putting return state
at the end of any reducers, but I think that TypeScript should catch this case, createStore should only accept a reducer of the form (state: S | undefined, action: Action) => S
Which versions of Redux, and which browser and OS are affected by this issue? Did this work in previous versions of Redux?
I’m testing with 4.0.4, haven’t tried any other versions.
Issue Analytics
- State:
- Created 4 years ago
- Comments:18 (10 by maintainers)
Top GitHub Comments
This is because we coerce the INIT and REPLACE actions to your Action type:
https://github.com/reduxjs/redux/blob/25f8a6c92773967d20641c6c239f31c1b01dd459/src/createStore.ts#L340 https://github.com/reduxjs/redux/blob/25f8a6c92773967d20641c6c239f31c1b01dd459/src/createStore.ts#L286
Perhaps we can make something like
reducer(state: State, action: ReduxActions<MyActions>) => State
that will include the internal actions?We ran into a similar (or exactly the same?) issue where the reducer type incorrectly constrains the set of allowed actions.
The Usage with TypeScript guide recommends typing the
action
parameter as the union of action types the reducer specifically reacts to:But that’s too constraining. A Redux reducer must expect and correctly handle any action of the general-purpose
Action
type, i.e., an object with atype
field.TypeScript then refuses to compile 100% valid code that calls the reducer:
Both these statements fail with:
If I understand the current types correctly, they are great for providing autocomplete hints, but are not that good at the main job of type checking, i.e., checking correctness of the compiled program.