@@ -251,44 +251,43 @@ interface State {
251251 count: number ;
252252}
253253
254- export class StatefulCounterWithDefault extends React .Component <StatefulCounterWithDefaultProps , State > {
255- // to make defaultProps strictly typed we need to explicitly declare their type
256- // @see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/11640
257- static defaultProps: DefaultProps = {
258- initialCount: 0 ,
259- };
260-
261- props: StatefulCounterWithDefaultProps & DefaultProps ;
254+ export const StatefulCounterWithDefault: React .ComponentClass <StatefulCounterWithDefaultProps > =
255+ class extends React .Component <StatefulCounterWithDefaultProps & DefaultProps > {
256+ // to make defaultProps strictly typed we need to explicitly declare their type
257+ // @see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/11640
258+ static defaultProps: DefaultProps = {
259+ initialCount: 0 ,
260+ };
262261
263- state: State = {
264- count: this .props .initialCount ,
265- };
262+ state: State = {
263+ count: this .props .initialCount ,
264+ };
266265
267- componentWillReceiveProps({ initialCount }: StatefulCounterWithDefaultProps ) {
268- if (initialCount != null && initialCount !== this .props .initialCount ) {
269- this .setState ({ count: initialCount });
266+ componentWillReceiveProps({ initialCount }: StatefulCounterWithDefaultProps ) {
267+ if (initialCount != null && initialCount !== this .props .initialCount ) {
268+ this .setState ({ count: initialCount });
269+ }
270270 }
271- }
272271
273- handleIncrement = () => {
274- this .setState ({ count: this .state .count + 1 });
275- }
272+ handleIncrement = () => {
273+ this .setState ({ count: this .state .count + 1 });
274+ }
276275
277- render() {
278- const { handleIncrement } = this ;
279- const { label } = this .props ;
280- const { count } = this .state ;
276+ render() {
277+ const { handleIncrement } = this ;
278+ const { label } = this .props ;
279+ const { count } = this .state ;
281280
282- return (
283- <div >
284- <span >{ label } : { count } </span >
285- <button type = " button" onClick = { handleIncrement } >
286- { ` Increment ` }
287- </button >
288- </div >
289- );
290- }
291- }
281+ return (
282+ <div >
283+ <span >{ label } : { count } </span >
284+ <button type = " button" onClick = { handleIncrement } >
285+ { ` Increment ` }
286+ </button >
287+ </div >
288+ );
289+ }
290+ };
292291
293292` ` `
294293
@@ -342,7 +341,7 @@ Adds state to a stateless counter
342341
343342` ` ` tsx
344343import * as React from ' react' ;
345- import { Diff as Subtract } from ' react-redux-typescript ' ;
344+ import { Subtract } from ' utility-types ' ;
346345
347346// These props will be subtracted from original component type
348347interface WrappedComponentProps {
@@ -414,7 +413,7 @@ Adds error handling using componentDidCatch to any component
414413
415414` ` ` tsx
416415import * as React from ' react' ;
417- import { Diff as Subtract } from ' react-redux-typescript ' ;
416+ import { Subtract } from ' utility-types ' ;
418417
419418const MISSING_ERROR = ' Error was swallowed during propagation.' ;
420419
@@ -521,15 +520,15 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
521520import { connect } from ' react-redux' ;
522521
523522import { RootState } from ' @src/redux' ;
524- import { actions , CountersSelectors } from ' @src/redux/counters' ;
523+ import { countersActions , CountersSelectors } from ' @src/redux/counters' ;
525524import { SFCCounter } from ' @src/components' ;
526525
527526const mapStateToProps = (state : RootState ) => ({
528527 count: CountersSelectors .getReduxCounter (state ),
529528});
530529
531530export const SFCCounterConnected = connect (mapStateToProps , {
532- onIncrement: actions .increment ,
531+ onIncrement: countersActions .increment ,
533532})(SFCCounter );
534533
535534` ` `
@@ -558,15 +557,15 @@ import { bindActionCreators } from 'redux';
558557import { connect } from ' react-redux' ;
559558
560559import { RootState , Dispatch } from ' @src/redux' ;
561- import { actions } from ' @src/redux/counters' ;
560+ import { countersActions } from ' @src/redux/counters' ;
562561import { SFCCounter } from ' @src/components' ;
563562
564563const mapStateToProps = (state : RootState ) => ({
565564 count: state .counters .reduxCounter ,
566565});
567566
568567const mapDispatchToProps = (dispatch : Dispatch ) => bindActionCreators ({
569- onIncrement: actions .increment ,
568+ onIncrement: countersActions .increment ,
570569}, dispatch );
571570
572571export const SFCCounterConnectedVerbose =
@@ -597,7 +596,7 @@ export default () => (
597596import { connect } from ' react-redux' ;
598597
599598import { RootState } from ' @src/redux' ;
600- import { actions , CountersSelectors } from ' @src/redux/counters' ;
599+ import { countersActions , CountersSelectors } from ' @src/redux/counters' ;
601600import { SFCCounter } from ' @src/components' ;
602601
603602export interface SFCCounterConnectedExtended {
@@ -609,7 +608,7 @@ const mapStateToProps = (state: RootState, ownProps: SFCCounterConnectedExtended
609608});
610609
611610export const SFCCounterConnectedExtended = connect (mapStateToProps , {
612- onIncrement: actions .increment ,
611+ onIncrement: countersActions .increment ,
613612})(SFCCounter );
614613
615614` ` `
@@ -647,7 +646,7 @@ All that without losing type-safety! Please check this very short [Tutorial](htt
647646` ` ` tsx
648647import { createAction } from ' typesafe-actions' ;
649648
650- export const actions = {
649+ export const countersActions = {
651650 increment: createAction (' INCREMENT' ),
652651 add: createAction (' ADD' , (amount : number ) => ({
653652 type: ' ADD' ,
@@ -660,10 +659,10 @@ export const actions = {
660659
661660` ` ` tsx
662661import store from ' @src/store' ;
663- import { actions } from ' @src/redux/counters' ;
662+ import { countersActions } from ' @src/redux/counters' ;
664663
665664// store.dispatch(actionCreators.increment(1)); // Error: Expected 0 arguments, but got 1.
666- store .dispatch (actions .increment ()); // OK => { type: "INCREMENT" }
665+ store .dispatch (countersActions .increment ()); // OK => { type: "INCREMENT" }
667666
668667` ` `
669668</p></details>
@@ -738,7 +737,7 @@ import { getType } from 'typesafe-actions';
738737
739738import { RootAction } from ' @src/redux' ;
740739
741- import { actions } from ' ./' ;
740+ import { countersActions } from ' ./' ;
742741
743742export type State = {
744743 readonly reduxCounter: number ;
@@ -747,11 +746,11 @@ export type State = {
747746export const reducer = combineReducers <State , RootAction >({
748747 reduxCounter : (state = 0 , action ) => {
749748 switch (action .type ) {
750- case getType (actions .increment ):
751- return state + 1 ;
749+ case getType (countersActions .increment ):
750+ return state + 1 ; // action is type: { type: "INCREMENT"; }
752751
753- case getType (actions .add ):
754- return state + action .payload ;
752+ case getType (countersActions .add ):
753+ return state + action .payload ; // action is type: { type: "ADD"; payload: number; }
755754
756755 default :
757756 return state ;
@@ -804,21 +803,19 @@ Can be imported in various layers receiving or sending redux actions like: reduc
804803` ` ` tsx
805804// RootActions
806805import { RouterAction , LocationChangeAction } from ' react-router-redux' ;
807- import { getReturnOfExpression } from ' react-redux-typescript ' ;
806+ import { $call } from ' utility-types ' ;
808807
809- import { actions as countersAC } from ' @src/redux/counters' ;
810- import { actions as todosAC } from ' @src/redux/todos' ;
811- import { actions as toastsAC } from ' @src/redux/toasts' ;
808+ import { countersActions } from ' @src/redux/counters' ;
809+ import { todosActions } from ' @src/redux/todos' ;
810+ import { toastsActions } from ' @src/redux/toasts' ;
812811
813- export const allActions = {
814- ... countersAC ,
815- ... todosAC ,
816- ... toastsAC ,
817- } ;
812+ const returnsOfActions = [
813+ ... Object . values ( countersActions ) ,
814+ ... Object . values ( todosActions ) ,
815+ ... Object . values ( toastsActions ) ,
816+ ]. map ( $call ) ;
818817
819- const returnOfActions =
820- Object .values (allActions ).map (getReturnOfExpression );
821- type AppAction = typeof returnOfActions [number ];
818+ type AppAction = typeof returnsOfActions [number ];
822819type ReactRouterAction = RouterAction | LocationChangeAction ;
823820
824821export type RootAction =
@@ -875,25 +872,28 @@ export default store;
875872
876873### "redux-observable"
877874
875+ Use ` isActionOf ` helper to filter actions and to narrow ` RootAction ` union type to a specific "action type" down the stream.
876+
878877` ` ` tsx
879878import { combineEpics , Epic } from ' redux-observable' ;
880879import { isActionOf } from ' typesafe-actions' ;
881880import { Observable } from ' rxjs/Observable' ;
882881import { v4 } from ' uuid' ;
883882
884- import { RootAction , RootState , allActions } from ' @src/redux' ;
885- import { actions } from ' ./' ;
883+ import { RootAction , RootState } from ' @src/redux' ;
884+ import { todosActions } from ' @src/redux/todos' ;
885+ import { toastsActions } from ' ./' ;
886886
887887const TOAST_LIFETIME = 2000 ;
888888
889889const addTodoToast: Epic <RootAction , RootState > =
890890 (action$ , store ) => action$
891- .filter (isActionOf (allActions .addTodo ))
892- .concatMap ((action ) => {
891+ .filter (isActionOf (todosActions .addTodo ))
892+ .concatMap ((action ) => { // action is type: { type: "ADD_TODO"; payload: string; }
893893 const toast = { id: v4 (), text: action .payload };
894894
895- const addToast$ = Observable .of (actions .addToast (toast ));
896- const removeToast$ = Observable .of (actions .removeToast (toast .id ))
895+ const addToast$ = Observable .of (toastsActions .addToast (toast ));
896+ const removeToast$ = Observable .of (toastsActions .removeToast (toast .id ))
897897 .delay (TOAST_LIFETIME );
898898
899899 return addToast$ .concat (removeToast$ );
@@ -965,7 +965,9 @@ export type Actions = {
965965 type: typeof ADD ,
966966 payload: number ,
967967 },
968- };
968+ };
969+
970+ export type RootAction = Actions [keyof Actions ];
969971
970972export const actions = {
971973 increment : (): Actions [typeof INCREMENT ] => ({
@@ -979,6 +981,7 @@ export const actions = {
979981` ` `
980982
981983[⇧ back to top](#table-of-contents)
984+
982985---
983986
984987# Tools
@@ -1307,7 +1310,6 @@ node ./generator/bin/generate-readme.js
13071310
13081311# Project Examples
13091312
1310- https://github.com/piotrwitek/react-redux-typescript-starter-kit
13111313https://github.com/piotrwitek/react-redux-typescript-webpack-starter
13121314
13131315[⇧ back to top](#table-of-contents)
0 commit comments