piotrwitek / react-redux-typescript-guide

The complete guide to static typing in "React & Redux" apps using TypeScript
https://piotrwitek.github.io/react-redux-typescript-guide/
MIT License
13.35k stars 1.09k forks source link

MapDispatchToProps shorthand #205

Closed Vanuan closed 4 years ago

Vanuan commented 4 years ago

Is there a solution for mapDispatchToProps shorthand syntax?

interface IProps {
  action: () => void;
}

const MyComponent = ({ action }: IProps): JSX.Element => (
  <div onClick={action}>my component</div>
);

const action = actionCreator<null>('SOME_ACTION'); // bound to dispatch

connect(null, { action })(MyComponent);

I'm getting this error:

Type 'ActionCreator<void>' is not assignable to type '() => void'.  TS2769

Is there a way to fix it without changing prop types of MyComponent?

piotrwitek commented 4 years ago

Hey @Vanuan Yes, an example is here: https://github.com/piotrwitek/react-redux-typescript-guide#--redux-connected-counter-with-redux-thunk-integration

use this:

const mapDispatchToProps = (dispatch: Dispatch<Types.RootAction>) =>
  bindActionCreators(
    {
      onIncrement: incrementWithDelay,
    },
    dispatch
  );
Vanuan commented 4 years ago

But that's not a shorthand syntax

Vanuan commented 4 years ago

Shorthand syntax is this:

connect(null, { onIncrement: incrementWithDelay })
Vanuan commented 4 years ago

Is there any reason you want to be able to use a return value of the dispatch call?

e.g.: props.incrementWithDelay().then(doSomethingElse)

This looks like a smell. But I think return value can be safely ignored.

So () => Action<void> should be assignable to () => void

Vanuan commented 4 years ago

I've created a fix for typescript-fsa: https://github.com/aikoven/typescript-fsa/pull/82

Maybe you can use the same approach