npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

typescript-fsa-vanuan

v3.3.0

Published

Type-safe action creator utilities

Downloads

8

Readme

CHANGES:

Supports payload-less actions:

  • https://github.com/aikoven/typescript-fsa/pull/82

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

Usage

Basic

import actionCreatorFactory from 'typescript-fsa-vanuan';

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-vanuan';

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.