- Notifications
You must be signed in to change notification settings - Fork28
Type-safe action creator utilities
License
aikoven/typescript-fsa
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Action Creator library for TypeScript. Its goal is to provide type-safe experience with Flux actions with minimum boilerplate.Created actions are FSA-compliant:
interfaceAction<Payload>{type:string;payload:Payload;error?:boolean;meta?:Object;}
npm install --save typescript-fsa
importactionCreatorFactoryfrom'typescript-fsa';constactionCreator=actionCreatorFactory();// Specify payload shape as generic type argument.constsomethingHappened=actionCreator<{foo:string}>('SOMETHING_HAPPENED');// Get action creator type.console.log(somethingHappened.type);// SOMETHING_HAPPENED// Create action.constaction=somethingHappened({foo:'bar'});console.log(action);// {type: 'SOMETHING_HAPPENED', payload: {foo: 'bar'}}
Async Action Creators are objects with propertiesstarted
,done
andfailed
whose values are action creators. There is a number ofCompanion Packages that help with binding Async Action Creators to async processes.
importactionCreatorFactoryfrom'typescript-fsa';constactionCreator=actionCreatorFactory();// specify parameters and result shapes as generic type argumentsconstdoSomething=actionCreator.async<{foo:string},// parameter type{bar:number},// success type{code:number}// error type>('DO_SOMETHING');console.log(doSomething.started({foo:'lol'}));// {type: 'DO_SOMETHING_STARTED', payload: {foo: 'lol'}}console.log(doSomething.done({params:{foo:'lol'},result:{bar:42},}));// {type: 'DO_SOMETHING_DONE', payload: {// params: {foo: 'lol'},// result: {bar: 42},// }}console.log(doSomething.failed({params:{foo:'lol'},error:{code:42},}));// {type: 'DO_SOMETHING_FAILED', payload: {// params: {foo: 'lol'},// error: {code: 42},// }, error: true}
You can specify a prefix that will be prepended to all action types. This isuseful to namespace library actions as well as for large projects where it'sconvenient to keep actions near the component that dispatches them.
// MyComponent.actions.tsimportactionCreatorFactoryfrom'typescript-fsa';constactionCreator=actionCreatorFactory('MyComponent');constsomethingHappened=actionCreator<{foo:string}>('SOMETHING_HAPPENED');constaction=somethingHappened({foo:'bar'});console.log(action);// {type: 'MyComponent/SOMETHING_HAPPENED', payload: {foo: 'bar'}}
// actions.tsimportactionCreatorFactoryfrom'typescript-fsa';constactionCreator=actionCreatorFactory();exportconstsomethingHappened=actionCreator<{foo:string}>('SOMETHING_HAPPENED');exportconstsomethingAsync=actionCreator.async<{foo:string},{bar:string}>('SOMETHING_ASYNC');// reducer.tsimport{Action}from'redux';import{isType}from'typescript-fsa';import{somethingHappened,somethingAsync}from'./actions';typeState={bar:string};exportconstreducer=(state:State,action:Action):State=>{if(isType(action,somethingHappened)){// action.payload is inferred as {foo: string};action.payload.bar;// errorreturn{bar:action.payload.foo};}if(isType(action,somethingAsync.started)){return{bar:action.payload.foo};}if(isType(action,somethingAsync.done)){return{bar:action.payload.result.bar};}returnstate;};
// epic.tsimport{Action}from'redux';import{Observable}from'rxjs';import{somethingAsync}from'./actions';exportconstepic=(actions$:Observable<Action>)=>actions$.filter(somethingAsync.started.match).delay(2000).map(action=>{// action.payload is inferred as {foo: string};action.payload.bar;// errorreturnsomethingAsync.done({params:action.payload,result:{bar:'bar',},});});
- typescript-fsa-redux-saga
- typescript-fsa-redux-observable
- typescript-fsa-redux-thunk
- typescript-fsa-reducers
- Type-safe Flux Standard Actions (FSA) in React Using TypeScript FSA
- Type-safe Asynchronous Actions (Redux Thunk) Using TypeScript FSA
Creates Action Creator factory with optional prefix for action types.
prefix?: string
: Prefix to be prepended to action types as<prefix>/<type>
.defaultIsError?: Predicate
: Function that detects whether action is errorgiven the payload. Default ispayload => payload instanceof Error
.
ActionCreatorFactory<Payload>#(type: string, commonMeta?: object, isError?: boolean): ActionCreator<Payload>
Creates Action Creator that produces actions with giventype
and payload of typePayload
.
type: string
: Type of created actions.commonMeta?: object
: Metadata added to created actions.isError?: boolean
: Defines whether created actions are error actions.
ActionCreatorFactory#async<Params, Result, Error>(type: string, commonMeta?: object): AsyncActionCreators<Params, Result, Error>
Creates three Action Creators:
started: ActionCreator<Params>
done: ActionCreator<{params: Params, result: Result}>
failed: ActionCreator<{params: Params, error: Error}>
Useful to wrap asynchronous processes.
type: string
: Prefix for types of created actions, which will have types${type}_STARTED
,${type}_DONE
and${type}_FAILED
.commonMeta?: object
: Metadata added to created actions.
Creates action with given payload and metadata.
payload: Payload
: Action payload.meta?: object
: Action metadata. Merged withcommonMeta
of Action Creator.
Returnstrue
if action has the same type as action creator. DefinesType Guardthat lets TypeScript knowpayload
type inside blocks whereisType
returnedtrue
:
constsomethingHappened=actionCreator<{foo:string}>('SOMETHING_HAPPENED');if(isType(action,somethingHappened)){// action.payload has type {foo: string}}
Identical toisType
except it is exposed as a bound method of an actioncreator. Since it is bound and takes a single argument it is ideal for passingto a filtering function likeArray.prototype.filter
orRxJS'sObservable.prototype.filter
.
constsomethingHappened=actionCreator<{foo:string}>('SOMETHING_HAPPENED');constsomethingElseHappened=actionCreator<{bar:number}>('SOMETHING_ELSE_HAPPENED');if(somethingHappened.match(action)){// action.payload has type {foo: string}}constactionArray=[somethingHappened({foo:'foo'}),somethingElseHappened({bar:5}),];// somethingHappenedArray has inferred type Action<{foo: string}>[]constsomethingHappenedArray=actionArray.filter(somethingHappened.match);
For more on usingArray.prototype.filter
as a type guard, seethis github issue.
About
Type-safe action creator utilities