v5.0.0 - Rewrite and simplify `createAction` API #143
piotrwitek posted onGitHub
Is your feature request related to a real problem or use-case?
Currently, createAction
API is not optimal and require some unnecessary boilerplate code (historically it was created pre TS v3.0 so there was a lot of limitations having an impact on API shape):
const action = createAction('TYPE', resolve => {
return (name: string, id: string) => resolve(id);
});
Describe a solution including usage in code example
Today with recent TypeScript features I can finally rewrite the API to something simpler, more intuitive and more consistent across the board.
This will resolve few existing feature requests:
- Resolves #73
- Resolves #90
createAction
type User = { id: number, name: string };
const user: User = { id: 1, name: 'Piotr' };
const action1 = createAction('TYPE1')<string>();
action1(user.name); // => { type: 'TYPE1', payload: 'Piotr' }
const action2 = createAction(
'TYPE1',
(user: User) => user.name, // payload creator
)<string>();
action2(user); // => { type: 'TYPE1', payload: 'Piotr' }
const actionWithMeta1 = createAction('TYPE2')<string, number>();
actionWithMeta1(user.name, user.id); // => { type: 'TYPE2', payload: 'Piotr', meta: 1 }
const actionWithMeta2 = createAction(
'TYPE2',
(user: User) => user.name, // payload creator
(user: User) => user.id, // optional meta creator
)<string, number>();
actionWithMeta2(user); // => { type: 'TYPE2', payload: 'Piotr', meta: 1 }
createAsyncAction
const action = createAsyncAction(
'REQ_TYPE', 'SUCCESS_TYPE', 'FAILURE_TYPE', 'CANCEL_TYPE',
)<Request, Response, Error, undefined>();
const action = createAsyncAction(
['REQ_TYPE', (req: Request) => req], // request payload creator
['SUCCESS_TYPE', (res: Response) => res], // success payload creator
['FAILURE_TYPE', (err: Error) => err], // failure payload creator
'CANCEL_TYPE', // optional cancel payload creator
)();
const actionWithMeta = createAsyncAction(
'REQ_TYPE', 'SUCCESS_TYPE', 'FAILURE_TYPE', 'CANCEL_TYPE',
)<[Request, Meta], Response, [Error, Meta], undefined>();
const actionWithMeta = createAsyncAction(
['REQ_TYPE', (req: Request) => req, (req: Request) => 'meta'], // request payload & meta creators
['SUCCESS_TYPE', (res: Response) => res], // success payload creator
['FAILURE_TYPE', (err: Error) => err, (err: Error) => 'meta'], // failure payload & meta creators
'CANCEL_TYPE', // optional cancel payload creator
)();
createCustomAction
All remaining non-standard use-cases you will be able to cover with createCustomAction
const action1 = createCustomAction('TYPE1', (name: string) => ({ payload: name }));
const action2 = createCustomAction('TYPE2', (name: string, id: string) => ({
payload: name, meta: id,
}));
Who does this impact? Who is this for?
All TypeScript users
Additional context (optional)
createAction
and createStandardAction
will be deprecated because new createAction
will be able to replace their function.
In v5, the old API will be kept in deprecated
import so incremental migration is possible:
import { deprecated } from "typesafe-actions";
const { createAction, createStandardAction } = deprecated;