-
-
Notifications
You must be signed in to change notification settings - Fork 15.3k
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
Fixed the definition of 'Reducer<S>' for TypeScript 2.4. #2467
Conversation
+1 on this. Redux is unusable with Typescript 2.4 without this (or something like it.) See https://github.com/Microsoft/TypeScript/issues/16795 |
Could we use another way to fix this. export type Reducer<S, A extends Action = Action> = (state: S, action: A) => S; // Dispatch need to update too.
export interface Dispatch<A extends Action = Action> {
(action: A): A;
} |
Thanks for looking into this. Can someone also make a PR against the |
I tested morlay's suggestion inside my project. The alternative suggestion for the Reducer definition seems to work fine: export type Reducer<S, A extends Action = Action> = (state: S, action: A) => S; However, the suggestion for the Dispatch definition causes problems in the form of other compile errors. These may be resolvable, but I need to spend a little more time to verify that. In my project, I have no problem with the original Dispatch definition, and I am not sure if this redefinition is really needed. |
If you did change the Dispatch definition, it would probably need to be this: export interface Dispatch<S, A extends Action = Action> {
(action: A): A;
} The 'S' parameter was missing in morley's post. I'm still having trouble with even that substitution, however. |
Thanks for merging Daniel's fix, Tim. I think that's the right way to go for now. Hopefully this will get published soon. |
Thanks! |
@jimsugg 'S' parameter in Dispatch is not necessary. we can keep |
@morlay - Yes - that seems right. Not being closely familiar with all the ramifications of the declarations, as soon as I saw there were multiple other references to |
export interface MyAction extends Action {
// ...
}
|
Why was import AnyAction from "redux"
const rootState: RootState = rootReducer(undefined, {
type: 'ADD_TODO',
text: 'test',
} as AnyAction) // cast to new type in PR `AnyAction` With |
@lukescott - Just as an experiment, I suggest you try suggestion from @morlay to see if that works for you: export type Reducer<S, A extends Action = Action> = (state: S, action: A) => S; In my test, this also fixes the issue with TS 2.4. So this might be a better solution than the one than introduces AnyAction. |
Yep that works. This works as well: export type Reducer<S> = (state: S, action: Action) => S; |
@lukescott - To reiterate why this is happening (you asked why |
@jimsugg Looks like all my issues were TypeScript 2.4, and some fumbling on my part. |
Is there anyway to take advantage of this now, without waiting for it to be shipped? Or do I have to downgrade TS? |
@blocka You can use this: #2182 (comment) |
Could this not warrant a patch release? It's basically the only change since 3.7.1, so wouldn't have to worry about other changes. |
mark |
I add my request for a quick rollout of this fix. This is a blocking issue for Redux users wanting to move to TS 2.4. |
I guess this is a non-breaking change and can be released as a patch. |
@aikoven any idea when this new type def will be released? Is it safe to assume it will show up in v3.7.2? |
cc. @timdorr |
OK, 3.7.2 is out now. |
I'm not incredibly familiar with how to cope with this change. Would someone that is familiar with what has been done here be kind enough to take a look at this broken build? This is IRT the reference from DefinitelyTyped/DefinitelyTyped#17777 Error:
The The test that is failing is located here. |
@sbuzonas edit index.d.ts of redux in node modules and try the alternate Reducer definition that doesn't use AnyAction and see if that solves your issue. If it does it may need to be patched again. The AnyAction worked for me, but it may not work in all cases. |
@lukescott The alternative does work, the problem is on master the typescript version is 1.8 and fails to pass the test. The changes on the @huy-nguyen That PR would work, but it sacrifices the safety of type checking. It would allow a circumstance where you send an incorrect action to the wrong reducer. Edit: Second thought, that is exactly how the code behaves. All actions are passed to the reducer, and the reducer simply returns an untouched state if it isn't the expected action. |
This is going to be a bit roundabout, but bear with me. 😄
Stricter checks on generics in TypeScript 2.4 correctly errored on the fact that reducers passed to
combineReducers
were expected to be more general than they actually needed to be.Since the
A
type parameter was never used as part of the return type - it was only used as a constraint - the appropriate next step was to replace the parameter type ofA
with theAction
type directly:However, because of excess property checks, this introduced errors when object literals were passed directly to a reducer. For example:
Thus, I created a new
AnyAction
which is justAction
with an index signature. This type is separate fromAction
to avoid polluting subtypes ofAction
with an index signature.