Skip to content

Commit

Permalink
Additional overloads to avoid ambiguous isActionOf type resolution for
Browse files Browse the repository at this point in the history
  • Loading branch information
Vincent Pizzo committed Dec 19, 2018
1 parent 7c8e39c commit 54f2947
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 30 deletions.
14 changes: 14 additions & 0 deletions src/is-action-of.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,18 @@ describe('isActionOf', () => {
mappedPayloadMetaExpected,
]);
});

it('should correctly resolve assertions', () => {
const action = withMappedPayload(1234);
if (isActionOf([withMappedPayload, withMappedPayloadMeta], action)) {
expect(action.payload).toBe(1234);
} else {
fail('isActionOf assertion should work when not curried');
}
if (isActionOf([withMappedPayload, withMappedPayloadMeta])(action)) {
expect(action.payload).toBe(1234);
} else {
fail('isActionOf assertion should work when curried');
}
});
});
93 changes: 63 additions & 30 deletions src/is-action-of.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,43 @@ import { TypeMeta } from './types';

export type AC<T extends { type: string }> = ((...args: any[]) => T) &
TypeMeta<T['type']>;
export type ACs<
T1 extends { type: string },
T2 extends { type: string } = any,
T3 extends { type: string } = any,
T4 extends { type: string } = any,
T5 extends { type: string } = any
> =
| [AC<T1>]
| [AC<T1>, AC<T2>]
| [AC<T1>, AC<T2>, AC<T3>]
| [AC<T1>, AC<T2>, AC<T3>, AC<T4>]
| [AC<T1>, AC<T2>, AC<T3>, AC<T4>, AC<T5>];

/**
* @description (curried assert function) check if an action is the instance of given action-creator(s)
* @description it works with discriminated union types
* @inner If you need more than 5 arguments -> use switch
*/
export function isActionOf<A extends { type: string }, T1 extends A>(
actionCreators: [AC<T1>],
action: { type: string }
): action is [T1][number];
export function isActionOf<
A extends { type: string },
T1 extends A,
T2 extends A
>(
actionCreators: [AC<T1>, AC<T2>],
action: { type: string }
): action is [T1, T2][number];
export function isActionOf<
A extends { type: string },
T1 extends A,
T2 extends A,
T3 extends A
>(
actionCreators: [AC<T1>, AC<T2>, AC<T3>],
action: { type: string }
): action is [T1, T2, T3][number];
export function isActionOf<
A extends { type: string },
T1 extends A,
T2 extends A,
T3 extends A,
T4 extends A
>(
actionCreators: [AC<T1>, AC<T2>, AC<T3>, AC<T4>],
action: { type: string }
): action is [T1, T2, T3, T4][number];
export function isActionOf<
A extends { type: string },
T1 extends A,
Expand All @@ -28,12 +47,7 @@ export function isActionOf<
T4 extends A,
T5 extends A
>(
actionCreators:
| ACs<T1>
| ACs<T1, T2>
| ACs<T1, T2, T3>
| ACs<T1, T2, T3, T4>
| ACs<T1, T2, T3, T4, T5>,
actionCreators: [AC<T1>, AC<T2>, AC<T3>, AC<T4>, AC<T5>],
action: { type: string }
): action is [T1, T2, T3, T4, T5][number];

Expand All @@ -51,6 +65,31 @@ export function isActionOf<A extends { type: string }, T1 extends A>(
* @description it works with discriminated union types
* @inner If you need more than 5 arguments -> use switch
*/
export function isActionOf<A extends { type: string }, T1 extends A>(
actionCreators: [AC<T1>]
): (action: A) => action is [T1][number];
export function isActionOf<
A extends { type: string },
T1 extends A,
T2 extends A
>(actionCreators: [AC<T1>, AC<T2>]): (action: A) => action is [T1, T2][number];
export function isActionOf<
A extends { type: string },
T1 extends A,
T2 extends A,
T3 extends A
>(
actionCreators: [AC<T1>, AC<T2>, AC<T3>]
): (action: A) => action is [T1, T2, T3][number];
export function isActionOf<
A extends { type: string },
T1 extends A,
T2 extends A,
T3 extends A,
T4 extends A
>(
actionCreators: [AC<T1>, AC<T2>, AC<T3>, AC<T4>]
): (action: A) => action is [T1, T2, T3, T4][number];
export function isActionOf<
A extends { type: string },
T1 extends A,
Expand All @@ -59,12 +98,7 @@ export function isActionOf<
T4 extends A,
T5 extends A
>(
actionCreators:
| ACs<T1>
| ACs<T1, T2>
| ACs<T1, T2, T3>
| ACs<T1, T2, T3, T4>
| ACs<T1, T2, T3, T4, T5>
actionCreators: [AC<T1>, AC<T2>, AC<T3>, AC<T4>, AC<T5>]
): (action: A) => action is [T1, T2, T3, T4, T5][number];

/**
Expand All @@ -86,12 +120,11 @@ export function isActionOf<
>(
creatorOrCreators:
| AC<T1>
| (
| ACs<T1>
| ACs<T1, T2>
| ACs<T1, T2, T3>
| ACs<T1, T2, T3, T4>
| ACs<T1, T2, T3, T4, T5>),
| [AC<T1>]
| [AC<T1>, AC<T2>]
| [AC<T1>, AC<T2>, AC<T3>]
| [AC<T1>, AC<T2>, AC<T3>, AC<T4>]
| [AC<T1>, AC<T2>, AC<T3>, AC<T4>, AC<T5>],
actionOrNil?: A
) {
if (creatorOrCreators == null) {
Expand Down

0 comments on commit 54f2947

Please sign in to comment.