@types/react-redux package and had problems.Definitions by: in index.d.ts) so they can respond.The following (self-contained) component stopped working after upgrading @types/react-redux from v6.0.9 to v6.0.10:
import * as React from "react";
import { connect } from "react-redux";
import { Dispatch } from "redux";
interface Item {
id: number;
content: string;
}
interface RootState {
items: Item[];
}
interface StateProps {
items: RootState["items"];
}
interface DispatchProps {
remove: (item: Item) => () => void;
}
function BaseItemList({ items, remove }: StateProps & DispatchProps) {
return (
<ol>
{items.map((item) => (
<li key={item.id}>
{item.content}
<button onClick={remove(item)}>
Remove
</button>
</li>
))}
</ol>
);
}
const mapStateToProps = ({ items }: RootState): StateProps => ({ items });
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({
remove: (item) => () => dispatch({ type: "REMOVE_ITEM", item }),
});
export const ItemList = connect(mapStateToProps, mapDispatchToProps)(BaseItemList);
After the upgrade, the last line lets TS complain with error TS2345:
Argument of type '({ items, remove }: StateProps & DispatchProps) => Element' is not assignable to parameter of type 'ComponentType<Matching<StateProps & { remove: () => void; }, StateProps & DispatchProps>>'.
Type '({ items, remove }: StateProps & DispatchProps) => Element' is not assignable to type 'FunctionComponent<Matching<StateProps & { remove: () => void; }, StateProps & DispatchProps>>'.
Types of parameters '__0' and 'props' are incompatible.
Type 'Matching<StateProps & { remove: () => void; }, StateProps & DispatchProps> & { children?: ReactNode; }' is not assignable to type 'StateProps & DispatchProps'.
Type 'Matching<StateProps & { remove: () => void; }, StateProps & DispatchProps> & { children?: ReactNode; }' is not assignable to type 'DispatchProps'.
Types of property 'remove' are incompatible.
Type '() => void' is not assignable to type '(item: Item) => () => void'.
Type 'void' is not assignable to type '() => void'. [2345]
You issue seems to be the duplicate of https://github.com/DefinitelyTyped/DefinitelyTyped/issues/30740
It was addressed in https://github.com/DefinitelyTyped/DefinitelyTyped/pull/30760
P.S. once https://github.com/DefinitelyTyped/DefinitelyTyped/pull/30760 will be merged you'll still get error, because (as far as I can understand), your DispatchProps should be defined like:
interface DispatchProps {
remove: (item: Item) => void;
}
That's explained by redux-thunk middleware documentation: https://github.com/reduxjs/redux-thunk#composition:
Any return value from the inner function will be available as the return value of
dispatchitself.
Thanks @surgeboris, but when defining the DispatchProps as you suggested, then the button's onClick handler is wrong:
Type 'void' is not assignable to type '(event: MouseEvent<HTMLButtonElement>) => void'.
Am I missing something?
@martinandert No, you're right. I've misread your case. It's actually interesting one, I didn't think of it.
I'll try to address it in #30760, once I'll have time.
I'll try to address it in #30760, once I'll have time.
Ok, thanks. Since my issue is actually the result of a regression introduced in v6.0.10, shouldn't it be reverted until it's properly fixed?
@martinandert I'm not aware of a possibility to revert package in DefinitelyTyped. I suppose that they do not provide such a possibility, because npm does not allow freely unpublish packages after left-pad chaos.
You can just revert to v6.0.9 in your project though.
I'm not aware of a possibility to revert package in DefinitelyTyped. I suppose that they do not provide such a possibility, because npm does not allow freely unpublish packages after left-pad chaos.
Sorry, I wasn't clear. With "revert" I mean re-releasing the "good" v6.0.9 as v6.0.11, leaving out the "bad" v6.0.10.
With "revert" I mean re-releasing the "good" v6.0.9 as v6.0.11, leaving out the "bad" v6.0.10.
I'm not sure how to do that either.
AFAIK I can only create a PR with revert commit, but as my previous experience shows that'll take more than a week for review and merge.
IMO it's easier to create a PR with a fix (which I did, and it was supposed to be merged soon, but it's now in hold because I need to address your issue).
Thanks @surgeboris, but when defining the
DispatchPropsas you suggested, then the button'sonClickhandler is wrong:Type 'void' is not assignable to type '(event: MouseEvent<HTMLButtonElement>) => void'.Am I missing something?
Kinda. OnClick react prop expects to get a function, not a function result. You need to use bind here.
interface DispatchProps {
remove: (item: Item) => void;
}
onClick={remove.bind(null, item)}
You can also use an arrow function but it may be forbidden by your tslint.
onClick={() => remove(item)}
Kinda. OnClick react prop expects to get a function, not a function result. You need to use bind here.
@tup1tsa onClick might expect function result if this result is a function itself (i.e. if we're calling higher-order function in onClick's value expression). This is exactly the case here. Please do not pay attention to the typing (it was buggy, fixed in #30760), take a look at the definition of remove in mapDispatchToProps function above.
You need to use bind here.
Then you're going to bind a higher order function. But you'll still need to call it to get an actual action handler that should be passed to onClick.
My fix was merged and I'm no longer able to reproduce the error for @types/[email protected].
@martinandert can you close this issue?
Works for me, thanks @surgeboris!