|
1 | 1 | import { Dispatch } from 'redux'
|
2 |
| -import { ActionCreatorWithPayload, createAction } from './createAction' |
| 2 | +import { createAction } from './createAction' |
3 | 3 |
|
4 | 4 | export type Await<T> = T extends {
|
5 | 5 | then(onfulfilled?: (value: infer U) => unknown): unknown
|
@@ -42,45 +42,64 @@ export function createAsyncThunk<
|
42 | 42 | undefined
|
43 | 43 | >
|
44 | 44 | >(type: ActionType, payloadCreator: PayloadCreator) {
|
| 45 | + // TODO This results in some hideous-looking inferred types for the actions |
45 | 46 | type ActionParams = Parameters<PayloadCreator>[0]['args']
|
46 | 47 |
|
47 |
| - const fulfilled = createAction(type) as ActionCreatorWithPayload< |
48 |
| - { args: ActionParams; result: Await<ReturnType<PayloadCreator>> }, |
49 |
| - ActionType |
50 |
| - > |
| 48 | + const fulfilled = createAction( |
| 49 | + type + '/fulfilled', |
| 50 | + (result: Await<ReturnType<PayloadCreator>>, args: ActionParams) => { |
| 51 | + return { |
| 52 | + payload: result, |
| 53 | + meta: { args } |
| 54 | + } |
| 55 | + } |
| 56 | + ) |
51 | 57 |
|
52 |
| - const pending = createAction(type + '/pending') as ActionCreatorWithPayload< |
53 |
| - { args: ActionParams }, |
54 |
| - string |
55 |
| - > |
| 58 | + const pending = createAction(type + '/pending', (args: ActionParams) => { |
| 59 | + return { |
| 60 | + payload: undefined, |
| 61 | + meta: { args } |
| 62 | + } |
| 63 | + }) |
56 | 64 |
|
57 |
| - const finished = createAction(type + '/finished') as ActionCreatorWithPayload< |
58 |
| - { args: ActionParams }, |
59 |
| - string |
60 |
| - > |
| 65 | + const finished = createAction(type + '/finished', (args: ActionParams) => { |
| 66 | + return { |
| 67 | + payload: undefined, |
| 68 | + meta: { args } |
| 69 | + } |
| 70 | + }) |
61 | 71 |
|
62 |
| - const rejected = createAction(type + '/rejected') as ActionCreatorWithPayload< |
63 |
| - { args: ActionParams; error: Error }, |
64 |
| - string |
65 |
| - > |
| 72 | + const rejected = createAction( |
| 73 | + type + '/rejected', |
| 74 | + (error: Error, args: ActionParams) => { |
| 75 | + return { |
| 76 | + payload: undefined, |
| 77 | + error, |
| 78 | + meta: { args } |
| 79 | + } |
| 80 | + } |
| 81 | + ) |
66 | 82 |
|
67 | 83 | function actionCreator(args?: ActionParams) {
|
68 | 84 | return async (dispatch: any, getState: any, extra: any) => {
|
69 | 85 | try {
|
70 |
| - dispatch(pending({ args })) |
| 86 | + dispatch(pending(args)) |
| 87 | + // TODO Also ugly types |
71 | 88 | const result: Await<ReturnType<PayloadCreator>> = await payloadCreator({
|
72 | 89 | args,
|
73 | 90 | dispatch,
|
74 | 91 | getState,
|
75 | 92 | extra
|
76 | 93 | })
|
| 94 | + |
77 | 95 | // TODO How do we avoid errors in here from hitting the catch clause?
|
78 |
| - return dispatch(fulfilled({ args, result })) |
| 96 | + return dispatch(fulfilled(result, args)) |
79 | 97 | } catch (err) {
|
80 | 98 | // TODO Errors aren't serializable
|
81 |
| - dispatch(rejected({ args, error: err })) |
| 99 | + dispatch(rejected(err, args)) |
82 | 100 | } finally {
|
83 |
| - dispatch(finished({ args })) |
| 101 | + // TODO IS there really a benefit from a "finished" action? |
| 102 | + dispatch(finished(args)) |
84 | 103 | }
|
85 | 104 | }
|
86 | 105 | }
|
|
0 commit comments