Skip to content

Commit 1d993f6

Browse files
authored
Merge pull request #96 from piotrwitek/dispatch-and-connect-improvements
Added new typing connect section and improved Dispatch typing with re…
2 parents 9bcca5b + add352d commit 1d993f6

File tree

5 files changed

+76
-4
lines changed

5 files changed

+76
-4
lines changed

README.md

+38-2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ This gives you the power to prioritize our work and support the project contribu
6161
- [Store Configuration](#store-configuration) 📝 __UPDATED__
6262
- [Async Flow](#async-flow) 📝 __UPDATED__
6363
- [Selectors](#selectors)
64+
- [Typing connect](#typing-connect) 🌟 __NEW__
6465
- [Tools](#tools)
6566
- [TSLint](#tslint)
6667
- [Jest](#jest)
@@ -637,7 +638,7 @@ A decent alternative I can recommend is to use `() => any` type, it will work ju
637638
638639
> There is alternative way to retain type soundness but it requires an explicit wrapping with `dispatch` and will be very tedious for the long run. See example below:
639640
```
640-
const mapDispatchToProps = (dispatch: Dispatch) => ({
641+
const mapDispatchToProps = (dispatch: Dispatch<ActionType>) => ({
641642
onIncrement: () => dispatch(actions.increment()),
642643
});
643644
```
@@ -692,7 +693,7 @@ const mapStateToProps = (state: Types.RootState) => ({
692693
count: state.counters.reduxCounter,
693694
});
694695

695-
const mapDispatchToProps = (dispatch: Dispatch) => bindActionCreators({
696+
const mapDispatchToProps = (dispatch: Dispatch<Types.RootAction>) => bindActionCreators({
696697
onIncrement: countersActions.increment,
697698
}, dispatch);
698699

@@ -1110,6 +1111,41 @@ export const getFilteredTodos = createSelector(getTodos, getTodosFilter, (todos,
11101111
11111112
---
11121113
1114+
## Typing connect
1115+
1116+
Below snippet can be find in the `playground/` folder, you can checkout the repo and follow all dependencies to understand the bigger picture.
1117+
`playground/src/connected/sfc-counter-connected-verbose.tsx`
1118+
1119+
```tsx
1120+
import Types from 'Types';
1121+
1122+
import { bindActionCreators, Dispatch } from 'redux';
1123+
import { connect } from 'react-redux';
1124+
1125+
import { countersActions } from '../features/counters';
1126+
import { SFCCounter, SFCCounterProps } from '../components';
1127+
1128+
// `state` parameter needs a type annotation to type-check the correct shape of a state object but also it'll be used by "type inference" to infer the type of returned props
1129+
const mapStateToProps = (state: Types.RootState, ownProps: SFCCounterProps) => ({
1130+
count: state.counters.reduxCounter,
1131+
});
1132+
1133+
// `dispatch` parameter needs a type annotation to type-check the correct shape of an action object when using dispatch function
1134+
const mapDispatchToProps = (dispatch: Dispatch<Types.RootAction>) => bindActionCreators({
1135+
onIncrement: countersActions.increment,
1136+
// without using action creators, this will be validated using your RootAction union type
1137+
// onIncrement: () => dispatch({ type: "counters/INCREMENT" }),
1138+
}, dispatch);
1139+
1140+
// NOTE: We don't need to pass generic type arguments to neither connect nor mapping functions because type inference will do all this work automatically. So there's really no reason to increase the noise ratio in your codebase!
1141+
export const SFCCounterConnectedVerbose =
1142+
connect(mapStateToProps, mapDispatchToProps)(SFCCounter);
1143+
```
1144+
1145+
[⇧ back to top](#table-of-contents)
1146+
1147+
---
1148+
11131149
# Tools
11141150
11151151
## TSLint

docs/markdown/1_react.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ A decent alternative I can recommend is to use `() => any` type, it will work ju
177177
178178
> There is alternative way to retain type soundness but it requires an explicit wrapping with `dispatch` and will be very tedious for the long run. See example below:
179179
```
180-
const mapDispatchToProps = (dispatch: Dispatch) => ({
180+
const mapDispatchToProps = (dispatch: Dispatch<ActionType>) => ({
181181
onIncrement: () => dispatch(actions.increment()),
182182
});
183183
```

docs/markdown/2_redux.md

+35
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,38 @@ When creating a store instance we don't need to provide any additional types. It
138138
::example='../../playground/src/features/todos/selectors.ts'::
139139

140140
[⇧ back to top](#table-of-contents)
141+
142+
---
143+
144+
## Typing connect
145+
146+
Below snippet can be find in the `playground/` folder, you can checkout the repo and follow all dependencies to understand the bigger picture.
147+
`playground/src/connected/sfc-counter-connected-verbose.tsx`
148+
149+
```tsx
150+
import Types from 'Types';
151+
152+
import { bindActionCreators, Dispatch } from 'redux';
153+
import { connect } from 'react-redux';
154+
155+
import { countersActions } from '../features/counters';
156+
import { SFCCounter, SFCCounterProps } from '../components';
157+
158+
// `state` parameter needs a type annotation to type-check the correct shape of a state object but also it'll be used by "type inference" to infer the type of returned props
159+
const mapStateToProps = (state: Types.RootState, ownProps: SFCCounterProps) => ({
160+
count: state.counters.reduxCounter,
161+
});
162+
163+
// `dispatch` parameter needs a type annotation to type-check the correct shape of an action object when using dispatch function
164+
const mapDispatchToProps = (dispatch: Dispatch<Types.RootAction>) => bindActionCreators({
165+
onIncrement: countersActions.increment,
166+
// without using action creators, this will be validated using your RootAction union type
167+
// onIncrement: () => dispatch({ type: "counters/INCREMENT" }),
168+
}, dispatch);
169+
170+
// NOTE: We don't need to pass generic type arguments to neither connect nor mapping functions because type inference will do all this work automatically. So there's really no reason to increase the noise ratio in your codebase!
171+
export const SFCCounterConnectedVerbose =
172+
connect(mapStateToProps, mapDispatchToProps)(SFCCounter);
173+
```
174+
175+
[⇧ back to top](#table-of-contents)

docs/markdown/_toc.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
- [Store Configuration](#store-configuration) 📝 __UPDATED__
1818
- [Async Flow](#async-flow) 📝 __UPDATED__
1919
- [Selectors](#selectors)
20+
- [Typing connect](#typing-connect) 🌟 __NEW__
2021
- [Tools](#tools)
2122
- [TSLint](#tslint)
2223
- [Jest](#jest)

playground/src/connected/sfc-counter-connected-verbose.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const mapStateToProps = (state: Types.RootState) => ({
99
count: state.counters.reduxCounter,
1010
});
1111

12-
const mapDispatchToProps = (dispatch: Dispatch) => bindActionCreators({
12+
const mapDispatchToProps = (dispatch: Dispatch<Types.RootAction>) => bindActionCreators({
1313
onIncrement: countersActions.increment,
1414
}, dispatch);
1515

0 commit comments

Comments
 (0)