Skip to content

Commit 5b2fb41

Browse files
authored
Merge pull request #180 from Cryrivers/master
Make typings compatible with Redux 4.0.0
2 parents 4f96ec0 + edcadd1 commit 5b2fb41

File tree

5 files changed

+92
-44
lines changed

5 files changed

+92
-44
lines changed

index.d.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1-
import {Middleware, Dispatch} from "redux";
1+
import { Middleware, Action, AnyAction } from "redux";
22

3-
4-
export type ThunkAction<R, S, E> = (dispatch: Dispatch<S>, getState: () => S,
5-
extraArgument: E) => R;
6-
7-
declare module "redux" {
8-
export interface Dispatch<S> {
9-
<R, E>(asyncAction: ThunkAction<R, S, E>): R;
10-
}
3+
export interface ThunkDispatch<S, E, A extends Action> {
4+
<T extends A>(action: T): T;
5+
<R>(asyncAction: ThunkAction<R, S, E, A>): R;
116
}
127

8+
export type ThunkAction<R, S, E, A extends Action> = (
9+
dispatch: ThunkDispatch<S, E, A>,
10+
getState: () => S,
11+
extraArgument: E
12+
) => R;
1313

14-
declare const thunk: Middleware & {
15-
withExtraArgument(extraArgument: any): Middleware;
16-
};
14+
export type ThunkMiddleware<S = {}, A extends Action = AnyAction, E = undefined> = Middleware<ThunkDispatch<S, E, A>, S, ThunkDispatch<S, E, A>>;
15+
16+
declare const thunk: ThunkMiddleware & {
17+
withExtraArgument<E>(extraArgument: E): ThunkMiddleware<{}, AnyAction, E>
18+
}
1719

1820
export default thunk;

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@
6969
"eslint-config-airbnb": "1.0.2",
7070
"eslint-plugin-react": "^4.1.0",
7171
"mocha": "^2.2.5",
72-
"redux": "^3.4.0",
72+
"redux": "~4.0.0",
7373
"rimraf": "^2.5.2",
74-
"typescript": "^1.8.10",
75-
"typescript-definition-tester": "0.0.4",
74+
"typescript": "~2.6.2",
75+
"typings-tester": "^0.3.1",
7676
"webpack": "^1.12.14"
7777
}
7878
}

test/index.js

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import chai from 'chai';
22
import thunkMiddleware from '../src/index';
3-
import * as tt from 'typescript-definition-tester';
3+
import { checkDirectory } from 'typings-tester';
44

55

66
describe('thunk middleware', () => {
@@ -97,12 +97,8 @@ describe('thunk middleware', () => {
9797
describe('TypeScript definitions', function test() {
9898
this.timeout(0);
9999

100-
it('should compile against index.d.ts', (done) => {
101-
tt.compileDirectory(
102-
__dirname,
103-
fileName => fileName.match(/\.ts$/),
104-
() => done()
105-
);
100+
it('should compile against index.d.ts', () => {
101+
checkDirectory(__dirname);
106102
});
107103
});
108104
});

test/tsconfig.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"compilerOptions": {
3+
"strict": true
4+
},
5+
"files": [
6+
"./*.ts"
7+
]
8+
}

test/typescript.ts

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,75 @@
1-
import {Store, Middleware} from 'redux';
2-
import thunk, {ThunkAction} from '../index.d.ts';
1+
import { createStore, applyMiddleware } from 'redux';
2+
import thunk, { ThunkAction, ThunkMiddleware } from '../index';
33

4+
type State = {
5+
foo: string;
6+
};
47

5-
declare const store: Store<{foo: string}>;
8+
type Actions = { type: 'FOO' } | { type: 'BAR', result: number };
69

7-
store.dispatch(dispatch => {
8-
dispatch({type: 'FOO'});
9-
});
10+
type ThunkResult<R> = ThunkAction<R, State, undefined, Actions>;
1011

11-
store.dispatch((dispatch, getState) => {
12-
const state = getState();
12+
const initialState: State = {
13+
foo: 'foo'
14+
};
1315

14-
const foo: string = state.foo;
15-
});
16+
function fakeReducer(state: State = initialState, action: Actions): State {
17+
return state;
18+
}
1619

17-
const middleware: Middleware = thunk.withExtraArgument('bar');
20+
const store = createStore(fakeReducer, applyMiddleware(thunk as ThunkMiddleware<State, Actions>));
1821

19-
store.dispatch((dispatch, getState, extraArg) => {
20-
console.log(extraArg);
22+
store.dispatch(dispatch => {
23+
dispatch({ type: 'FOO' });
24+
// typings:expect-error
25+
dispatch({ type: 'BAR' })
26+
dispatch({ type: 'BAR', result: 5 })
27+
// typings:expect-error
28+
store.dispatch({ type: 'BAZ'});
2129
});
2230

23-
const thunkAction: ThunkAction<void, {foo: string}, {bar: number}> =
24-
(dispatch, getState, extraArg) => {
25-
const foo: string = getState().foo;
26-
const bar: number = extraArg.bar;
27-
28-
dispatch({type: 'FOO'});
31+
function testGetState(): ThunkResult<void> {
32+
return (dispatch, getState) => {
33+
const state = getState();
34+
const foo: string = state.foo;
35+
dispatch({ type: 'FOO' });
36+
// typings:expect-error
37+
dispatch({ type: 'BAR'});
38+
dispatch({ type: 'BAR', result: 5 });
39+
// typings:expect-error
40+
dispatch({ type: 'BAZ'});
41+
// Can dispatch another thunk action
42+
dispatch(anotherThunkAction());
2943
};
44+
}
3045

31-
const thunkActionDispatchOnly: ThunkAction<void, {}, {}> = dispatch => {
32-
dispatch({type: 'FOO'});
33-
};
46+
function anotherThunkAction(): ThunkResult<string> {
47+
return (dispatch, getState) => {
48+
dispatch({ type: 'FOO' });
49+
return 'hello';
50+
}
51+
}
52+
53+
store.dispatch({ type: 'FOO' });
54+
// typings:expect-error
55+
store.dispatch({ type: 'BAR' })
56+
store.dispatch({ type: 'BAR', result: 5 })
57+
// typings:expect-error
58+
store.dispatch({ type: 'BAZ'});
59+
store.dispatch(testGetState());
60+
61+
const storeThunkArg = createStore(
62+
fakeReducer,
63+
applyMiddleware(thunk.withExtraArgument('bar') as ThunkMiddleware<State, Actions, string>)
64+
);
65+
66+
storeThunkArg.dispatch((dispatch, getState, extraArg) => {
67+
const bar: string = extraArg;
68+
store.dispatch({ type: 'FOO' });
69+
// typings:expect-error
70+
store.dispatch({ type: 'BAR' })
71+
store.dispatch({ type: 'BAR', result: 5 })
72+
// typings:expect-error
73+
store.dispatch({ type: 'BAZ'});
74+
console.log(extraArg);
75+
});

0 commit comments

Comments
 (0)