• Stars
    star
    610
  • Rank 70,993 (Top 2 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 7 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Type-safe action creator utilities

TypeScript FSA npm version Build Status

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

interface Action<Payload> {
  type: string;
  payload: Payload;
  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. There is a number of Companion Packages that help with binding Async Action Creators to async processes.

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');
export const somethingAsync =
  actionCreator.async<{foo: string},
                      {bar: string}
                     >('SOMETHING_ASYNC');


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

type State = {bar: string};

export 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};
  }

  if (isType(action, somethingAsync.started)) {
    return {bar: action.payload.foo};
  }

  if (isType(action, somethingAsync.done)) {
    return {bar: action.payload.result.bar};
  }

  return state;
};

redux-observable

// epic.ts
import {Action} from 'redux';
import {Observable} from 'rxjs';
import {somethingAsync} from './actions';

export const epic = (actions$: Observable<Action>) =>
  actions$.filter(somethingAsync.started.match)
    .delay(2000)
    .map(action => {
      // action.payload is inferred as {foo: string};

      action.payload.bar;  // error

      return somethingAsync.done({
        params: action.payload,
        result: {
          bar: 'bar',
        },
      });
    });

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 as <prefix>/<type>.
  • defaultIsError?: Predicate: Function that detects whether action is error given the payload. Default is payload => payload instanceof Error.

ActionCreatorFactory<Payload>#(type: string, commonMeta?: object, isError?: boolean): ActionCreator<Payload>

Creates Action Creator that produces actions with given type and payload of type Payload.

  • 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.

ActionCreator<Payload>#(payload: Payload, meta?: object): Action<Payload>

Creates action with given payload and metadata.

  • payload: Payload: Action payload.
  • meta?: object: Action metadata. Merged with commonMeta of Action Creator.

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}
}

ActionCreator#match(action: Action): boolean

Identical to isType except it is exposed as a bound method of an action creator. Since it is bound and takes a single argument it is ideal for passing to a filtering function like Array.prototype.filter or RxJS's Observable.prototype.filter.

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

if (somethingHappened.match(action)) {
  // action.payload has type {foo: string}
}

const actionArray = [
  somethingHappened({foo: 'foo'}),
  somethingElseHappened({bar: 5}),
];

// somethingHappenedArray has inferred type Action<{foo: string}>[]
const somethingHappenedArray = actionArray.filter(somethingHappened.match);

For more on using Array.prototype.filter as a type guard, see this github issue.

More Repositories

1

typescript-fsa-redux-saga

TypeScript FSA utilities for redux-saga
TypeScript
61
star
2

typings-tester

TypeScript
46
star
3

assert-never

Helper function for exhaustive checks of discriminated unions in TypeScript
TypeScript
35
star
4

foundationdb-exporter

Prometheus exporter for FoundationDB
TypeScript
19
star
5

typescript-immutable-utils

Type-safe immutability helpers for simple objects and arrays
TypeScript
5
star
6

vscode-slice

Slice Language Support for Visual Studio Code
3
star
7

keyper

UNMAINTAINED Persistence layer/in-memory data store
TypeScript
3
star
8

riemann-statsd-backend

Riemann backend for StatsD
TypeScript
2
star
9

typed-material-ui

DEPRECATED TypeScript definitions for Material-UI
2
star
10

slice2md

Compiles Slice files to Markdown.
TypeScript
2
star
11

slice2ts

Compiles Slice files to TypeScript.
TypeScript
2
star
12

ice-health-check

Docker health checker for ZeroC ICE
JavaScript
2
star
13

kekal

UNMAINTAINED A library for long-lived asynchronously initialized values β€” Permanents.
TypeScript
2
star
14

typed-ice

TypeScript definitions for ZeroC ICE
TypeScript
2
star
15

slice-loader

Webpack loader for code generated by ZeroC ICE
JavaScript
2
star
16

ice-dump

Encode and decode ZeroC Ice objects manually into Ice binary format.
JavaScript
1
star
17

slice2json

Parser for the Slice language
TypeScript
1
star
18

prettier-plugin-slice

Prettier plugin for the Slice language
TypeScript
1
star
19

recombine

Utilities for combining Redux reducers
TypeScript
1
star
20

ice-to-plain

Convert Ice stuff to and from plain JS objects
TypeScript
1
star
21

json-stringifier

Alternative to JSON.stringify() that supports altering the behavior of the stringification process at string level
TypeScript
1
star
22

ice-utils

DEPRECATED A set of utilities that makes using ZeroC ICE 3.6 with JS easier
TypeScript
1
star
23

ice-redux-devtools

Redux DevTools Extension add-on that handles serialization of ZeroC Ice stuff
TypeScript
1
star