Skip to content
This repository has been archived by the owner on Mar 31, 2022. It is now read-only.

Commit

Permalink
Fix typescript errors...READ
Browse files Browse the repository at this point in the history
Because I had to install a beta version of redux in order to get it to
stop throwing dispatch type errors, based on advice from some issue, I
had a subsequent problem  with redux-thunk not yet supporting that new
version.

There was a pull request already though to fix this, so I pulled the
changes from [that pr] into my redux-thunk npm package to get it to
work.  I have a comment on that PR as to exactly what I did.

As of this moment though, that PR still isn't quite finished and thus
this does not compile.

[that pr]: reduxjs/redux-thunk#180
  • Loading branch information
0livare committed Mar 6, 2018
1 parent 1204f98 commit ce93730
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 71 deletions.
6 changes: 2 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,16 @@
"react-redux": "^5.0.7",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"redux": "^3.7.2",
"redux-thunk": "^2.2.0",
"whatwg-fetch": "1.0.0"
"redux-thunk": "^2.2.0"
},
"devDependencies": {
"@types/node": "^9.4.6",
"@types/react": "^16.0.38",
"@types/react-dom": "^16.0.4",
"@types/react-hot-loader": "^3.0.6",
"@types/redux-immutable-state-invariant": "^2.0.4",
"@types/redux-thunk": "^2.1.0",
"@types/webpack-env": "^1.13.5",
"@types/whatwg-fetch": "0.0.33",
"autoprefixer": "^8.0.0",
"awesome-typescript-loader": "^3.5.0",
"babel-cli": "6.16.0",
Expand Down
12 changes: 7 additions & 5 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ import * as React from 'react'
import * as ReactDOM from "react-dom"
import { AppContainer } from 'react-hot-loader'
import { configureStore } from './redux'
import Root from './components/Root'
import { loadCourses } from './redux'
import { loadAuthors } from './redux'

import { loadCourses, loadAuthors } from './redux'
import { ThunkAction } from 'redux-thunk'
import 'babel-core/register'
import 'babel-polyfill'
import { Store } from 'redux'

//@ts-ignore
import Root from './components/Root'

const store = configureStore()
const store: Store = configureStore()
store.dispatch(loadCourses())
store.dispatch(loadAuthors())

Expand Down
10 changes: 1 addition & 9 deletions src/redux/RootState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,4 @@ import { IAuthor } from './authors'
export type RootState = {
authors: IAuthor[],
courses: ICourse[],
}

export class InitialState {
authors: IAuthor[]
courses: ICourse[]
}

let initialState = new InitialState();
export { initialState }
}
41 changes: 24 additions & 17 deletions src/redux/authors/authorActions.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
import { createAction } from 'typesafe-actions'
import {Action, ActionCreator, Dispatch} from 'redux'
import {ThunkAction} from 'redux-thunk'

import { ThunkResult } from '../'
import authorApi from '../../api/authorApi'
import { RootState } from '../RootState'
import { IAuthor, LOAD_AUTHORS_SUCCESS } from './types'
import { OtherAction } from '../'


/*************************
* ACTION TYPES/CREATORS
*************************/

export type LoadAuthorsSuccessAction = {
type: LOAD_AUTHORS_SUCCESS,
authors: IAuthor[],
};

export function LoadAuthorsSuccess(authors: IAuthor[]): LoadAuthorsSuccessAction {
export function loadAuthorsSuccess(authors: IAuthor[]): AuthorAction {
return {type: LOAD_AUTHORS_SUCCESS, authors}
}


export const loadAuthors: ActionCreator<
ThunkAction<Promise<Action>, RootState, void>
> = () => {
return async (dispatch: Dispatch<Action, RootState>): Promise<Action> => {
const authors: IAuthor[] = await authorApi.getAllAuthors()
return dispatch({
type: LOAD_AUTHORS_SUCCESS,
authors
})
/*************************
* ACTION TYPE UNION
*************************/

export type AuthorAction =
| LoadAuthorsSuccessAction
| OtherAction
;


/*************************
* THUNKS
*************************/

export function loadAuthors() : ThunkResult<void> {
return async (dispatch, getState) => {
const authors = await authorApi.getAllAuthors()
dispatch(loadAuthorsSuccess(authors))
}
}
9 changes: 2 additions & 7 deletions src/redux/authors/authorReducer.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import * as types from './types'
import { combineReducers } from 'redux'
import { getType } from 'typesafe-actions'
import { IAuthor, LoadAuthorsSuccessAction, OtherAction } from '../'
import { RootState, initialState } from '../RootState'
import { RootState, AuthorAction } from '../'
import initialState from '../initialState'

type AuthorAction =
LoadAuthorsSuccessAction |
OtherAction;

export function authorReducer(state = initialState.authors, action: AuthorAction) {
switch (action.type) {
Expand Down
38 changes: 23 additions & 15 deletions src/redux/courses/courseActions.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import * as types from './types'
import courseApi from '../../api/courseApi'
import {Action, ActionCreator, Dispatch} from 'redux'
import { RootState, InitialState } from '../RootState'

import {
ICourse,
LOAD_COURSES_SUCCESS,
CREATE_COURSE_SUCCESS,
UPDATE_COURSE_SUCCESS,
} from './types'
import { ThunkAction } from 'redux-thunk';
import { OtherAction, ThunkResult } from '../'

/*************************
* ACTION CREATORS
* ACTION TYPES/CREATORS
*************************/

export type LoadCoursesSuccessAction = {
Expand All @@ -39,28 +37,38 @@ export function updateCourseSuccess(course: ICourse): UpdateCourseSuccessAction
return { type: types.UPDATE_COURSE_SUCCESS, course }
}


/*************************
* ACTION TYPE UNION
*************************/

export type CourseAction =
| LoadCoursesSuccessAction
| CreateCourseSuccessAction
| UpdateCourseSuccessAction
| OtherAction
;

/*************************
* THUNKS
*************************/

export const loadCourses: ActionCreator<
ThunkAction<Promise<Action>, RootState, void>
> = () => {
return async (dispatch: Dispatch<Action, RootState>): Promise<Action> => {
const allCourses = await courseApi.getAllCourses()
return dispatch(loadCoursesSuccess(allCourses))
export function loadCourses() : ThunkResult<ICourse[]> {
return async (dispatch, getState) => {
const allCourses = await courseApi.getAllCourses()
console.log('loaded courses', allCourses)
dispatch(loadCoursesSuccess(allCourses))
return allCourses
}
}

export const saveCourse: ActionCreator<
ThunkAction<Promise<Action>, RootState, void>
> = (course: ICourse) => {
return async (dispatch: Dispatch<Action, RootState>): Promise<Action> => {
export function saveCourse(course: ICourse) : ThunkResult<void> {
return async (dispatch, getState) => {
const savedCourse = await courseApi.saveCourse(course)
const action = course.id
? updateCourseSuccess(savedCourse)
: createCourseSuccess(savedCourse)

return dispatch(action)
dispatch(action)
}
}
15 changes: 4 additions & 11 deletions src/redux/courses/courseReducer.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as types from './types'
import { RootState, initialState, ICourse, OtherAction } from '../'
import { ICourse, CourseAction } from '../'
import initialState from '../initialState'
import { LoadCoursesSuccessAction,
CreateCourseSuccessAction,
UpdateCourseSuccessAction } from './courseActions'
CreateCourseSuccessAction,
UpdateCourseSuccessAction } from './courseActions'

/*
* It's important to note that each reducer only handles
Expand All @@ -12,14 +13,6 @@ import { LoadCoursesSuccessAction,
* below is initialized to the 'courses' portion of the
* initial state.
*/

type CourseAction =
LoadCoursesSuccessAction |
CreateCourseSuccessAction |
UpdateCourseSuccessAction |
OtherAction ;


export function courseReducer(state=initialState.courses, action: CourseAction) {
switch(action.type) {
case types.LOAD_COURSES_SUCCESS:
Expand Down
14 changes: 13 additions & 1 deletion src/redux/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,19 @@ export * from './courses'
export * from './store/configureStore'

export * from './rootReducer'
export * from './RootState'
export * from './rootState'
export * from './rootAction'

export type OtherAction = { type: '' };
export const OtherAction : OtherAction = { type: '' };

import { Action, ActionCreator } from 'redux'
import { ThunkAction } from 'redux-thunk'
import { RootState } from './rootState'
import { RootAction } from './rootAction'
/**
* A type for specifying the eventual return type of
* any Thunk. `T` is the eventual return type of
* the thunk.
*/
export type ThunkResult<T> = ThunkAction<Promise<T>, RootState, {}, RootAction>
10 changes: 10 additions & 0 deletions src/redux/initialState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ICourse } from './courses'
import { IAuthor } from './authors'

// Note that this class is an instance of type RootState
class InitialState {
authors: IAuthor[] = []
courses: ICourse[] = []
}

export default new InitialState()
7 changes: 7 additions & 0 deletions src/redux/rootAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { AuthorAction } from './authors'
import { CourseAction } from './courses'

export type RootAction =
| AuthorAction
| CourseAction
;
5 changes: 3 additions & 2 deletions src/redux/store/configureStore.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { createStore, applyMiddleware } from 'redux'
import reduxImmutableStateInvariant from 'redux-immutable-state-invariant'
import thunk from 'redux-thunk'
import { RootState, rootReducer, initialState } from '../'
import { RootState, rootReducer } from '../'
import initialState from '../initialState'

function configureStore(state: RootState = initialState) {
const middleware = applyMiddleware(
Expand All @@ -11,7 +12,7 @@ function configureStore(state: RootState = initialState) {

const store = createStore(
rootReducer,
state,
{}, // TODO WHY WON'T `state` WORK HERE!?!
middleware
)

Expand Down

0 comments on commit ce93730

Please sign in to comment.