I'm trying to create a function to generate my redux action creators.
Let's say we have these types for our actions:
export type DeleteAction = {
type: typeof BLAH_DELETE;
payload: {
id: string;
};
};
export type EditAction = {
type: typeof BLAH_EDIT;
payload: {
id: string;
name: string;
};
};
export MyAction = DeleteAction | EditAction
Now in the actions file, I would like to create my actions in this way:
export const deleteBlah = makeActionCreator<MyAction>('BLAH_DELETE');
// Expected Behaviour
deleteBlah({ id: '' }) // Correct
deleteBlah({ id: '', name: '' }) // Error
export const editBlah = makeActionCreator<MyAction>('BLAH_EDIT');
// Expected Behaviour
editBlah({ id: '', name: '' }) // Correct
editBlah({ id: '' }) // Error
Here is the makeActionCreator function:
export const makeActionCreator = <A extends { type: string; payload: any }>(type: A['type']) => (
payload: ActionPayload<ExtractAction<A, A['type']>>,
) => ({
type,
payload,
});
type ExtractAction<A, T> = A extends { type: T } ? A : never;
type ActionPayload<T extends { payload: any }> = Pick<T['payload'], keyof T['payload']>;
The problem is I don't know how can I pass the action type which is provided in actions file to the ExtractAction<A, A['type']> so, the payload is always valid for all possible options of A.
ActionPayloadlook like? I guess it would be:type ActionPayload<A> = A extends { payload: any } ? A['payload'] : never;export const deleteBlah = makeActionCreator<DeleteAction>('BLAH_DELETE');DeleteActionitself has the action type so it doesn't make sense to send it again as a param, but we need that param as well :)