Skip to content

Added new typing connect section and improved Dispatch typing with re… #96

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

Merged
merged 1 commit into from
Sep 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ This gives you the power to prioritize our work and support the project contribu
- [Store Configuration](#store-configuration) 📝 __UPDATED__
- [Async Flow](#async-flow) 📝 __UPDATED__
- [Selectors](#selectors)
- [Typing connect](#typing-connect) 🌟 __NEW__
- [Tools](#tools)
- [TSLint](#tslint)
- [Jest](#jest)
Expand Down Expand Up @@ -637,7 +638,7 @@ A decent alternative I can recommend is to use `() => any` type, it will work ju

> 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:
```
const mapDispatchToProps = (dispatch: Dispatch) => ({
const mapDispatchToProps = (dispatch: Dispatch<ActionType>) => ({
onIncrement: () => dispatch(actions.increment()),
});
```
Expand Down Expand Up @@ -692,7 +693,7 @@ const mapStateToProps = (state: Types.RootState) => ({
count: state.counters.reduxCounter,
});

const mapDispatchToProps = (dispatch: Dispatch) => bindActionCreators({
const mapDispatchToProps = (dispatch: Dispatch<Types.RootAction>) => bindActionCreators({
onIncrement: countersActions.increment,
}, dispatch);

Expand Down Expand Up @@ -1110,6 +1111,41 @@ export const getFilteredTodos = createSelector(getTodos, getTodosFilter, (todos,

---

## Typing connect

Below snippet can be find in the `playground/` folder, you can checkout the repo and follow all dependencies to understand the bigger picture.
`playground/src/connected/sfc-counter-connected-verbose.tsx`

```tsx
import Types from 'Types';

import { bindActionCreators, Dispatch } from 'redux';
import { connect } from 'react-redux';

import { countersActions } from '../features/counters';
import { SFCCounter, SFCCounterProps } from '../components';

// `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
const mapStateToProps = (state: Types.RootState, ownProps: SFCCounterProps) => ({
count: state.counters.reduxCounter,
});

// `dispatch` parameter needs a type annotation to type-check the correct shape of an action object when using dispatch function
const mapDispatchToProps = (dispatch: Dispatch<Types.RootAction>) => bindActionCreators({
onIncrement: countersActions.increment,
// without using action creators, this will be validated using your RootAction union type
// onIncrement: () => dispatch({ type: "counters/INCREMENT" }),
}, dispatch);

// 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!
export const SFCCounterConnectedVerbose =
connect(mapStateToProps, mapDispatchToProps)(SFCCounter);
```

[⇧ back to top](#table-of-contents)

---

# Tools

## TSLint
Expand Down
2 changes: 1 addition & 1 deletion docs/markdown/1_react.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ A decent alternative I can recommend is to use `() => any` type, it will work ju

> 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:
```
const mapDispatchToProps = (dispatch: Dispatch) => ({
const mapDispatchToProps = (dispatch: Dispatch<ActionType>) => ({
onIncrement: () => dispatch(actions.increment()),
});
```
Expand Down
35 changes: 35 additions & 0 deletions docs/markdown/2_redux.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,38 @@ When creating a store instance we don't need to provide any additional types. It
::example='../../playground/src/features/todos/selectors.ts'::

[⇧ back to top](#table-of-contents)

---

## Typing connect

Below snippet can be find in the `playground/` folder, you can checkout the repo and follow all dependencies to understand the bigger picture.
`playground/src/connected/sfc-counter-connected-verbose.tsx`

```tsx
import Types from 'Types';

import { bindActionCreators, Dispatch } from 'redux';
import { connect } from 'react-redux';

import { countersActions } from '../features/counters';
import { SFCCounter, SFCCounterProps } from '../components';

// `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
const mapStateToProps = (state: Types.RootState, ownProps: SFCCounterProps) => ({
count: state.counters.reduxCounter,
});

// `dispatch` parameter needs a type annotation to type-check the correct shape of an action object when using dispatch function
const mapDispatchToProps = (dispatch: Dispatch<Types.RootAction>) => bindActionCreators({
onIncrement: countersActions.increment,
// without using action creators, this will be validated using your RootAction union type
// onIncrement: () => dispatch({ type: "counters/INCREMENT" }),
}, dispatch);

// 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!
export const SFCCounterConnectedVerbose =
connect(mapStateToProps, mapDispatchToProps)(SFCCounter);
```

[⇧ back to top](#table-of-contents)
1 change: 1 addition & 0 deletions docs/markdown/_toc.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- [Store Configuration](#store-configuration) 📝 __UPDATED__
- [Async Flow](#async-flow) 📝 __UPDATED__
- [Selectors](#selectors)
- [Typing connect](#typing-connect) 🌟 __NEW__
- [Tools](#tools)
- [TSLint](#tslint)
- [Jest](#jest)
Expand Down
2 changes: 1 addition & 1 deletion playground/src/connected/sfc-counter-connected-verbose.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const mapStateToProps = (state: Types.RootState) => ({
count: state.counters.reduxCounter,
});

const mapDispatchToProps = (dispatch: Dispatch) => bindActionCreators({
const mapDispatchToProps = (dispatch: Dispatch<Types.RootAction>) => bindActionCreators({
onIncrement: countersActions.increment,
}, dispatch);

Expand Down