You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
By limiting the action parameter to the subset of types your reducer cares about, we introduce a bug where the inferred type of action in the default case is never. This is because when you do a union type in typescript, it implicitly adds | never at the end;
Steps to Reproduce
typeMyActionTypes=ActionType1|ActionType2;//implicitly ActionType1 | ActionType2 | neverconstMyReducer: Reducer<MyState,MyActionTypes>=(state=initState,action)=>{switch(action.type){caseactionTypes.TYPE_1:
returnhandleType1(state,action);//infers that action is ActionType1caseactionTypes.TYPE_2:
returnhandleType2(state,action);//infers that action is ActionType2default:
returnaction;//infers that action type is never, so it does not complain that the return type is invalid because it assumes this will never happen anyway}};
What is the expected behavior?
Have a type error if you return action from the default case
Environment Details
n/a
I found the original discussion that lead to this change, and while I get the convenience benefit of constraining the types to allow typescript to infer the action type for you, that comes with the cost of types not being correct and I think that's not the right tradeoff to make. I also get that this is a big breaking change that is difficult to make, but this seems like a really easy bug to make accidentally, and if someone heavily relies on typescript to catch type errors (which they should be able to do), this can affect them.
I think at worst, forcing you to do something like this is not a large cost to pay for correctness.
I'm also not sure if it's possible, but I think ideally, we could get the benefits of type inference without losing type safety. If there was some sort of "difference" operator in typescript, which was similar to unions and intersections but said A ~ B is types that are A and not B, then we could do something like this
I was hoping that Exclude<A, B> would be the difference type I was looking for, but it doesn't seem to work that way.
I'm not sure if the difference type is possible, and even if it is, if typescript can do the type inference we get currently while also realizing that in the default case, action is not never. But even if not, I think this is something that should be addressed.
The text was updated successfully, but these errors were encountered:
Prior Issues
none
What is the current behavior?
The reducer type is not type safe. It assumes you never reach your default case in the switch statement.
By limiting the action parameter to the subset of types your reducer cares about, we introduce a bug where the inferred type of action in the default case is
never
. This is because when you do a union type in typescript, it implicitly adds| never
at the end;Steps to Reproduce
What is the expected behavior?
Have a type error if you return action from the default case
Environment Details
n/a
I found the original discussion that lead to this change, and while I get the convenience benefit of constraining the types to allow typescript to infer the action type for you, that comes with the cost of types not being correct and I think that's not the right tradeoff to make. I also get that this is a big breaking change that is difficult to make, but this seems like a really easy bug to make accidentally, and if someone heavily relies on typescript to catch type errors (which they should be able to do), this can affect them.
I think at worst, forcing you to do something like this is not a large cost to pay for correctness.
I'm also not sure if it's possible, but I think ideally, we could get the benefits of type inference without losing type safety. If there was some sort of "difference" operator in typescript, which was similar to unions and intersections but said
A ~ B
is types that areA
and notB
, then we could do something like thisI was hoping that
Exclude<A, B>
would be the difference type I was looking for, but it doesn't seem to work that way.I'm not sure if the difference type is possible, and even if it is, if typescript can do the type inference we get currently while also realizing that in the default case, action is not
never
. But even if not, I think this is something that should be addressed.The text was updated successfully, but these errors were encountered: