Skip to content

Instantly share code, notes, and snippets.

@glendaviesnz
Forked from ghetolay/ngrx_actions.ts
Created February 28, 2017 02:00
Show Gist options
  • Save glendaviesnz/3a2f5d22454ee0de469008ba4b02734b to your computer and use it in GitHub Desktop.
Save glendaviesnz/3a2f5d22454ee0de469008ba4b02734b to your computer and use it in GitHub Desktop.
Pattern to build actions for ngrx
interface Action<T> {
type: T;
}
interface PayloadAction<T, R> {
readonly type: T;
payload: R;
}
interface ActionFactory<T> {
(): Action<T>;
type: T;
}
interface PayloadActionFactory<T, R> {
(payload: R): PayloadAction<T, R>;
type: T;
}
function newActionFactory<T extends string>(type: T|''): ActionFactory<T>;
function newActionFactory<T extends string, R>(type: T|'', payloadFunc: (payload: R) => R): PayloadActionFactory<T, R>;
function newActionFactory<T extends string, R>(type: T|'', payloadFunc?: (payload: R) => R): ActionFactory<T> | PayloadActionFactory<T, R> {
const actionBuilder = payloadFunc ?
<PayloadActionFactory<T, R>> function(payload: R): PayloadAction<T, R> {
return {
payload: payloadFunc(payload),
type: <T>type
};
} :
<ActionFactory<T>> function(): Action<T> {
return { type: <T>type };
}
;
actionBuilder.type = <T>type;
return actionBuilder;
}
//usage
const Action1 = newActionFactory('ACTION1');
/* Here we have to use a function mostly for typings but also allow user to define some logic to build the payload */
const Action2 = newActionFactory('ACTION2', (p: number) => p);
/* Here we need to do some boilerplate by repeting the structure or our actions
* This should be replaced with ts 2.3 with something like :
* `type Actions = returnType Action1 | returnType Action2`
*/
type Actions = Action<'ACTION1'> | PayloadAction<'ACTION2', number>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment