/typescript-fsa

Type-safe action creator utilities

Primary LanguageTypeScriptMIT LicenseMIT

TypeScript FSA npm version Build Status

A simple Action Creator library for TypeScript. Its goal is to provide simple yet type-safe experience with Flux actions. Created actions are FSA-compliant:

interface Action<P> {
  type: string;
  payload: P;
  error?: boolean;
  meta?: Object;
}

Installation

npm install --save typescript-fsa

Usage

Basic

import actionCreatorFactory from 'typescript-fsa';

const actionCreator = actionCreatorFactory();

// Specify payload shape as generic type argument. 
const somethingHappened = actionCreator<{foo: string}>('SOMETHING_HAPPENED');

// Get action creator type.
console.log(somethingHappened.type);  // SOMETHING_HAPPENED

// Create action.
const action = somethingHappened({foo: 'bar'});
console.log(action);  // {type: 'SOMETHING_HAPPENED', payload: {foo: 'bar'}}  

Async Action Creators

Async Action Creators are objects with properties started, done and failed whose values are action creators.

import actionCreatorFactory from 'typescript-fsa';

const actionCreator = actionCreatorFactory();

// specify parameters and result shapes as generic type arguments
const doSomething = 
  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}

Actions With Type Prefix

You can specify a prefix that will be prepended to all action types. This is useful to namespace library actions as well as for large projects where it's convenient to keep actions near the component that dispatches them.

// MyComponent.actions.ts
import actionCreatorFactory from 'typescript-fsa';

const actionCreator = actionCreatorFactory('MyComponent');

const somethingHappened = actionCreator<{foo: string}>('SOMETHING_HAPPENED');

const action = somethingHappened({foo: 'bar'});
console.log(action);  
// {type: 'MyComponent/SOMETHING_HAPPENED', payload: {foo: 'bar'}}  

Redux

// actions.ts
import actionCreatorFactory from 'typescript-fsa';

const actionCreator = actionCreatorFactory();

export const somethingHappened = 
  actionCreator<{foo: string}>('SOMETHING_HAPPENED');


// reducer.ts
import {Action} from 'redux';
import {isType} from 'typescript-fsa';
import {somethingHappened} from './actions';

type State = {bar: string};

const reducer = (state: State, action: Action): State => {
  if (isType(action, somethingHappened)) {
    // action.payload is inferred as {foo: string};
    
    action.payload.bar;  // error
    
    return {bar: action.payload.foo};
  }

  return state; 
};

Companion packages

Resources

API

actionCreatorFactory(prefix?: string, defaultIsError?: Predicate): ActionCreatorFactory

Creates Action Creator factory with optional prefix for action types.

  • prefix?: string: Prefix to be prepended to action types.
  • defaultIsError?: Predicate: Function that detects whether action is error given the payload. Default is payload => payload instanceof Error.

isType(action: Action, actionCreator: ActionCreator): boolean

Returns true if action has the same type as action creator. Defines Type Guard that lets TypeScript know payload type inside blocks where isType returned true:

const somethingHappened = actionCreator<{foo: string}>('SOMETHING_HAPPENED');

if (isType(action, somethingHappened)) {
  // action.payload has type {foo: string};
}