@ryym @weswigham
This change to types/react-redux : 1efe02587a531ed9bc8abe07705494982f2d0b55 was released as a patch version (types/[email protected]), but is a breaking change because it is types for redux 4.x, not 3.x.
As a result, my project started using 5.0.18 (actually, it was a dependency of a dependency), resulting in many errors like this when building:
Argument of type 'ThunkAction<void, IAppState, undefined>' is not assignable to parameter of type 'AnyAction'.
I can fix by setting my version to types/[email protected], but if breaking changes like this are made on "patch" releases it seems to contradict the use of semver.
Was this a correct release (in which case, how should users like me prevent this happening in future), or should it have been released as a major release (types/[email protected])?
Tagging all listed authors of types/react-redux as listed https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-redux/index.d.ts#L3 because the issue message tells me to: @tkqubo, @thasner @kenzierocks @clayne11 @tansongyang @nicholasboll @mdibyo @pdeva
Wow, I didn't know that the change was published as a patch release...
I agree, it must be a new major version release.
In the FAQ in README, I found a section about major version update. Probably I should have followed this rule, but I overlooked it. Sorry 馃檱
Though I read the How can I contribute? guide before making a pull request, I could not find that FAQ section at that time.
So, I think we need to follow these steps to fix this issue.
v5 sub directory.@weswigham Is my understanding correct?
Yep, that sounds right
I reverted the change and it was published as @types/react-redux version 5.0.19.
The new pull request #25435 was merged and published as @types/react-redux 6.0.0!
I think all necessary fixes were done.
@Crashthatch Could you close this issue?
Looks good, thanks for fixing (I only tested 5.0.19, not v6.0.0, but that is working)
Thanks, @ryym, but what about this?
@ryym
For some reason I'm getting following error:
Failed to compile.
K:/app/node_modules/@types/react-redux/index.d.ts
(37,59): Generic type 'Dispatch' requires 2 type argument(s).
EDIT:
Nevermind, that's an issue with redux-thunk
@jeremejevs That's a strange. Your code compiles without errors in my environment.
redux - v4.0.0react-redux - v5.0.7@types/react-redux - v6.0.0typescript v2.8.3But a similar error was produced when I compiled with @types/react-redux v5.2.0.
Types of property 'store' are incompatible.
Type 'Store<{ foo: number; }, { type: "foo"; payload: number; }>'is not assignable to type 'Store<any> | undefined'.
Type 'Store<{ foo: number; }, { type: "foo"; payload: number; }>' is not assignable to type 'Store<any>'.
Types of property 'dispatch' are incompatible.
Type 'Dispatch<{ type: "foo"; payload: number; }>' is not assignable to type 'Dispatch<any>'.
Types of parameters 'action' and 'action' are incompatible.
Type 'A' is not assignable to type '{ type: "foo"; payload: number; }'.
Type 'Action' is not assignable to type '{ type: "foo"; payload: number; }'.
Property 'payload' is missing in type 'Action'.
Perhaps you are using @types/react-redux v5?
@ryym Here's a repro, run yarn tsc. Fresh tsconfig.json, straight out of tsc --init. The only change is the uncommented jsx line, so it doesn't complain about the lack of React.
I'm thinking that maybe you don't have strict enabled? It compiles fine without it.
@jeremejevs You're right, thanks for the reproduction repo.
The strict option enables the strictFunctionTypes option that checks type parameters _contravariantly_, and it produces the error. With this option, TypeScript disallows code like below:
type Action = {type: 'foo'; payload: number};
let myDispatch: Dispatch<Action> = store.dispatch;
let anyDispatch: Dispatch<AnyAction> = myDispatch; // Error
This is the cause of the compile error.
However, I found this code compiles:
type Action = {type: 'foo'; payload: number} | {type: 'bar'}; // Use union type
let myDispatch: Dispatch<Action> = store.dispatch;
let anyDispatch: Dispatch<AnyAction> = myDispatch; // OK
I guess this is because the union type becomes a super class of AnyAction.
{type: 'foo'} < AnyAction < {type: 'foo'} | {type: 'bar}
So your code compiles as well using the union type action.
import {Reducer, createStore} from 'redux';
import {Provider} from 'react-redux';
const reducer: Reducer<
{foo: number} | undefined, // State
{type: 'foo'; payload: number} | {type: 'bar'} // Action
> = state => state;
const store = createStore(reducer);
export const Whatever = () => (
<Provider store={store}>
<div>Whatever</div>
</Provider>
);
How about this workaround?
You can always use optional properties:
type Action = {type: 'foo'; payload?: number};
How about this?
@@ -33,7 +33,6 @@
type StatelessComponent<P> = React.StatelessComponent<P>;
type Component<P> = React.ComponentType<P>;
type ReactNode = React.ReactNode;
-type Store<S> = Redux.Store<S>;
type Dispatch<A extends Redux.Action = Redux.AnyAction> = Redux.Dispatch<A>;
type ActionCreator<A> = Redux.ActionCreator<A>;
@@ -313,18 +312,18 @@
withRef?: boolean
}
-export interface ProviderProps {
+export interface ProviderProps<A extends Redux.Action> {
/**
* The single Redux store in your application.
*/
- store?: Store<any>;
+ store?: Redux.Store<any, A>;
children?: ReactNode;
}
/**
* Makes the Redux store available to the connect() calls in the component hierarchy below.
*/
-export class Provider extends React.Component<ProviderProps, {}> { }
+export class Provider<A extends Redux.Action> extends React.Component<ProviderProps<A>, {}> { }
/**
* Creates a new <Provider> which will set the Redux Store on the passed key of the context. You probably only need this
@jeremejevs Seems great!
It resolves the compile error without breaking the current behavior.
Would you make a pull request? :)
@ryym Done :slightly_smiling_face: #25709
Most helpful comment
@ryym Done :slightly_smiling_face: #25709