Skip to content

Commit 9b8b8c4

Browse files
committed
Optional action payload
1 parent fbbd7ff commit 9b8b8c4

File tree

3 files changed

+82
-69
lines changed

3 files changed

+82
-69
lines changed

src/index.ts

+47-6
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export function isType<Payload>(
3232
return action.type === actionCreator.type;
3333
}
3434

35-
export interface ActionCreator<Payload> {
35+
interface ActionCreatorWithPayload<Payload> {
3636
type: string;
3737
/**
3838
* Identical to `isType` except it is exposed as a bound method of an action
@@ -70,14 +70,55 @@ export interface ActionCreator<Payload> {
7070
(payload: Payload, meta?: Meta): Action<Payload>;
7171
}
7272

73+
interface ActionCreatorWithoutPayload<Payload> {
74+
type: string;
75+
/**
76+
* Identical to `isType` except it is exposed as a bound method of an action
77+
* creator. Since it is bound and takes a single argument it is ideal for
78+
* passing to a filtering function like `Array.prototype.filter` or
79+
* RxJS's `Observable.prototype.filter`.
80+
*
81+
* @example
82+
*
83+
* const somethingHappened =
84+
* actionCreator<{foo: string}>('SOMETHING_HAPPENED');
85+
* const somethingElseHappened =
86+
* actionCreator<{bar: number}>('SOMETHING_ELSE_HAPPENED');
87+
*
88+
* if (somethingHappened.match(action)) {
89+
* // action.payload has type {foo: string}
90+
* }
91+
*
92+
* const actionArray = [
93+
* somethingHappened({foo: 'foo'}),
94+
* somethingElseHappened({bar: 5}),
95+
* ];
96+
*
97+
* // somethingHappenedArray has inferred type Action<{foo: string}>[]
98+
* const somethingHappenedArray =
99+
* actionArray.filter(somethingHappened.match);
100+
*/
101+
match: (action: AnyAction) => action is Action<Payload>;
102+
/**
103+
* Creates action without payload.
104+
*
105+
*/
106+
(): Action<Payload>;
107+
}
108+
109+
export type ActionCreator<Payload> =
110+
Payload extends void
111+
? ActionCreatorWithoutPayload<Payload> & ActionCreatorWithPayload<Payload>
112+
: ActionCreatorWithPayload<Payload>;
113+
73114
export type Success<Params, Result> = (
74-
| {params: Params}
75-
| (Params extends void ? {params?: Params} : never)) &
76-
({result: Result} | (Result extends void ? {result?: Result} : never));
115+
(Params extends void ? {params?: Params} : {params: Params})) &
116+
(Result extends void ? {result?: Result} : {result: Result});
77117

78118
export type Failure<Params, Error> = (
79-
| {params: Params}
80-
| (Params extends void ? {params?: Params} : never)) & {error: Error};
119+
(Params extends void
120+
? {params?: Params}
121+
: {params: Params})) & {error: Error};
81122

82123
export interface AsyncActionCreators<Params, Result, Error = {}> {
83124
type: string;

tests/typings/index.ts

+6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const actionCreator = actionCreatorFactory();
99
function testPayload() {
1010
const withPayload = actionCreator<{foo: string}>('WITH_PAYLOAD');
1111
const withoutPayload = actionCreator('WITHOUT_PAYLOAD');
12+
const withOrWithoutPayload = actionCreator<string | undefined>('WITH_ORWITHOUT_PAYLOAD')
1213

1314
// typings:expect-error
1415
const a = withPayload();
@@ -21,6 +22,11 @@ function testPayload() {
2122
const f = withoutPayload(undefined, {meta: 'meta'});
2223
// typings:expect-error
2324
const g = withoutPayload({foo: 'bar'});
25+
26+
const h = withOrWithoutPayload('string');
27+
//const i = withOrWithoutPayload();
28+
// typings:expect-error
29+
const j = withOrWithoutPayload(111);
2430
}
2531

2632
function testAsyncPayload() {

yarn.lock

+29-63
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,10 @@ ansi-styles@^2.2.1:
2727
version "2.2.1"
2828
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
2929

30-
ansi-styles@^3.2.1:
31-
version "3.2.1"
32-
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
33-
dependencies:
34-
color-convert "^1.9.0"
30+
arg@^4.1.0:
31+
version "4.1.3"
32+
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
33+
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
3534

3635
arr-diff@^2.0.0:
3736
version "2.0.0"
@@ -47,10 +46,6 @@ array-unique@^0.2.1:
4746
version "0.2.1"
4847
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
4948

50-
arrify@^1.0.0:
51-
version "1.0.1"
52-
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
53-
5449
babel-code-frame@^6.22.0:
5550
version "6.22.0"
5651
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
@@ -92,24 +87,6 @@ chalk@^1.1.0:
9287
strip-ansi "^3.0.0"
9388
supports-color "^2.0.0"
9489

95-
chalk@^2.3.0:
96-
version "2.3.2"
97-
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65"
98-
dependencies:
99-
ansi-styles "^3.2.1"
100-
escape-string-regexp "^1.0.5"
101-
supports-color "^5.3.0"
102-
103-
color-convert@^1.9.0:
104-
version "1.9.1"
105-
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed"
106-
dependencies:
107-
color-name "^1.1.1"
108-
109-
color-name@^1.1.1:
110-
version "1.1.3"
111-
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
112-
11390
colors@^1.1.2:
11491
version "1.1.2"
11592
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
@@ -143,10 +120,15 @@ defined@~1.0.0:
143120
version "1.0.0"
144121
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
145122

146-
diff@^3.1.0, diff@^3.2.0:
123+
diff@^3.2.0:
147124
version "3.2.0"
148125
resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
149126

127+
diff@^4.0.1:
128+
version "4.0.2"
129+
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
130+
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
131+
150132
es-abstract@^1.5.0:
151133
version "1.7.0"
152134
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.7.0.tgz#dfade774e01bfcd97f96180298c449c8623fb94c"
@@ -164,7 +146,7 @@ es-to-primitive@^1.1.1:
164146
is-date-object "^1.0.1"
165147
is-symbol "^1.0.1"
166148

167-
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
149+
escape-string-regexp@^1.0.2:
168150
version "1.0.5"
169151
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
170152

@@ -290,10 +272,6 @@ has-ansi@^2.0.0:
290272
dependencies:
291273
ansi-regex "^2.0.0"
292274

293-
has-flag@^3.0.0:
294-
version "3.0.0"
295-
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
296-
297275
has@^1.0.1, has@~1.0.1:
298276
version "1.0.1"
299277
resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28"
@@ -441,20 +419,14 @@ micromatch@^2.3.11:
441419
dependencies:
442420
brace-expansion "^1.0.0"
443421

444-
minimist@0.0.8, minimist@~0.0.1:
422+
minimist@~0.0.1:
445423
version "0.0.8"
446424
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
447425

448-
minimist@^1.2.0, minimist@~1.2.0:
426+
minimist@~1.2.0:
449427
version "1.2.0"
450428
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
451429

452-
mkdirp@^0.5.1:
453-
version "0.5.1"
454-
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
455-
dependencies:
456-
minimist "0.0.8"
457-
458430
normalize-path@^2.0.1:
459431
version "2.1.1"
460432
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
@@ -598,9 +570,10 @@ semver@^5.3.0:
598570
version "5.3.0"
599571
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
600572

601-
source-map-support@^0.5.3:
602-
version "0.5.6"
603-
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.6.tgz#4435cee46b1aab62b8e8610ce60f788091c51c13"
573+
source-map-support@^0.5.6:
574+
version "0.5.16"
575+
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042"
576+
integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==
604577
dependencies:
605578
buffer-from "^1.0.0"
606579
source-map "^0.6.0"
@@ -631,12 +604,6 @@ supports-color@^2.0.0:
631604
version "2.0.0"
632605
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
633606

634-
supports-color@^5.3.0:
635-
version "5.3.0"
636-
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0"
637-
dependencies:
638-
has-flag "^3.0.0"
639-
640607
tape@^4.6.2:
641608
version "4.6.3"
642609
resolved "https://registry.yarnpkg.com/tape/-/tape-4.6.3.tgz#637e77581e9ab2ce17577e9bd4ce4f575806d8b6"
@@ -659,18 +626,16 @@ through@~2.3.4, through@~2.3.8:
659626
version "2.3.8"
660627
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
661628

662-
ts-node@^6.0.0:
663-
version "6.0.3"
664-
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-6.0.3.tgz#28bf74bcad134fad17f7469dad04638ece03f0f4"
629+
ts-node@^8.4.0:
630+
version "8.6.2"
631+
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.6.2.tgz#7419a01391a818fbafa6f826a33c1a13e9464e35"
632+
integrity sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==
665633
dependencies:
666-
arrify "^1.0.0"
667-
chalk "^2.3.0"
668-
diff "^3.1.0"
634+
arg "^4.1.0"
635+
diff "^4.0.1"
669636
make-error "^1.1.1"
670-
minimist "^1.2.0"
671-
mkdirp "^0.5.1"
672-
source-map-support "^0.5.3"
673-
yn "^2.0.0"
637+
source-map-support "^0.5.6"
638+
yn "3.1.1"
674639

675640
tslib@^1.6.0:
676641
version "1.7.0"
@@ -725,6 +690,7 @@ wrappy@1:
725690
version "1.0.2"
726691
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
727692

728-
yn@^2.0.0:
729-
version "2.0.0"
730-
resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a"
693+
694+
version "3.1.1"
695+
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
696+
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==

0 commit comments

Comments
 (0)