Updated action
See original GitHub issueHi Nicholas.
This isn’t an issue; just a discussion, carrying on from the issue I raised the other day (#26).
I found this website: https://qiita.com/terrierscript/items/b9687f610a96ab964ab2 and although I can’t understand the text, I have managed to build upon the code. Here is the current solution that we quite like for our actions and I was hoping it might help you with your refactor.
import { Action } from 'redux'
type TPayloadFn<Args extends any[], R> = (...args: Args) => R
type TActionCreator<Args extends any[], A> = (...args: Args) => A
type TAction<T extends string, Payloads extends {} = {}> = Action<T> &
{ [K in keyof Payloads]: Payloads[K] }
function a<T extends string>(
type: T,
): { TYPE: T; create: TActionCreator<any[], TAction<T>> }
function a<T extends string, Args extends any[], R>(
type: T,
fn: TPayloadFn<Args, R>,
): { TYPE: T; create: TActionCreator<Args, TAction<T, R>> }
function a(type: string, payloadFn?: any) {
return {
TYPE: type,
create: (...args: any[]) => {
if (payloadFn) {
const extra = payloadFn(...args)
return { type, ...extra }
}
return { type }
},
}
}
This allows us to write our current actions…
export class ATestAction {
public static readonly TYPE = 'TEST/ACTION'
public static create(str: ATestAction['str']): ATestAction {
return { type: ATestAction.TYPE, str }
}
public readonly type = ATestAction.TYPE
public readonly str: string
}
as…
export const ATestAction = a('TEST/ACTION', (str: string) => ({ str }))
export type ATestAction = ReturnType<typeof ATestAction.create>
This allows us to get the redux type of the action with:
ATestAction.TYPE
Create a new action with:
ATestAction.create('some string')
/* Producing:
{
type: 'TEST/ACTION',
str: 'some string'
}
*/
And the TS type of the action with just:
ATestAction
(which was based on your suggestion from that other issue, thanks).
Now, I’d quite like to get the payloadFn even smaller, maybe even the same way you do:
export const ATestAction = a('TEST/ACTION', p<{str: string}>())
export type ATestAction = ReturnType<typeof ATestAction.create>
If you have found this helpful, I’d really appreciate it if you could take a look at how I’d achieve that.
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (3 by maintainers)
The type constant would be available, as it has is now, via a
type
property on the action creator function:foo.type
.The
action
property will probably be there, too. Although, with more recent versions of TypeScript, it’s likely unnecessary (the lib was written to work with 2.6, IIRC).The main reason for the change would be to remove the creation of class instances instead of plain objects, as creating instances necessitates clobbering the prototype for it to work with Redux.
Hi @cartant, just to let you know, we released our version, it’s called ‘a’: https://github.com/ArtosSystems/a It’s the first public version but has gone through 3 iterations until we landed on the current implementation. You are of course credited for all the help you provided me, thank-you.