-
-
Save glendaviesnz/3a2f5d22454ee0de469008ba4b02734b to your computer and use it in GitHub Desktop.
Pattern to build actions for ngrx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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