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

redux-action-method-ts

v1.0.1

Published

Helper library to automatically map methods to Redux actions

Downloads

4

Readme

redux-action-method-ts

Helper library to automatically map TypeScript methods to Redux actions.

Usage

Install by npm install redux-action-method-ts or directly taking the code (only one file) to your project. See the example for the usage.

Story

There are a few things I really hate with Redux when I studied about it recently:

  1. Defining action type constants and creating action objects
  2. Using switch-cases in reducer
  3. Handling type-unsafe payloads passed from action to reducer

For a long-time object oriented design practitioner like myself, TypeScript and React seems to be a light of hope brought into the dark JavaScript GUI developemnt world. However, when I see Redux commonly used with React, I feel I am drawn back to the darkness again by the dirty programming model above.

So here is my thought that makes more sense, at least for me if not for everyone.

  • Most of the time, an action can be equivalent to a method signature and its parameters that makes the state transition happen, if spoken in the object oriented terminologies. It is exactly like a method invocation packet created by an RPC client stub, and this analogy suggests that we should be able to come up with a generic mechanism to create actions based on the given interface definition without any manual effort.
  • If we got an action containing a method signature and its parameters as discussed above, we should be able to implement a generic reducer that dispatches the action to the designated method on an action handler object to make the actual state transition happen. This action handler should be bound with the reducer upfrount.
  • Let's say we had an interface that exposes the requierd actions as methods (such as increment() and add(x:number) if it was a counter application) with the return type generic. Then we should be able to use this same interface both to create actions (by returning an action object) and to implement the action handler.

Putting those thoughs together, I would like to write my Redux actions and reducers like this pseudo code. If you liked this idea, see the complete example and use it in your project.

import {Action, createStore} from "redux";
import {createActionCreator, createReducer} from "redux-action-method-ts"; // my fancy library

interface State { counter: number } // State for my counter application

// Define actions as an interface with the return type generic
// The return type will be specialized by action creators and action handlers respectively.
interface Actions<R> {
  increment(): R;
  add(x: number): R;
}

// Derive an action creator from the interface above
// A proxy of type Actions<Action> is created behind the scenes.
const actions = createActionCreator<Actions<Action>>();

// Implement the state transitions using the same interface
// Each method returns a function that takes the old state and returns the new state
// because the method itself does not take the state in the parameters.
class ActionHandler implements Actions<(s:State) => State> {
  increment() { return (s:State): State => ({...s, counter: s.counter + 1}) }
  add(x:number) { return (s:State): State => ({...s, counter: s.counter + x}) }
}

// Create a reducer by binding the action handler and the action creator above
const reducers = createReducer<State>(new ActionHandler(), actions, { counter: 0 });

// Now actions and reducers are ready to use.
const store = createStore(reducers);
store.dispatch(actions.increment());
store.dispatch(actions.add(5));
...

Also note that this approach is totally compatible with the usual Redux usage. You can use it when and only when you like it, and should be totally safe to mix it with other approaches.

Object Model

Conclusion

This small library allows you to use Redux without compromising your favorite object oriented design practice. All you need is to create an interface and an action handler as its implementation, then Redux actions and reducers can be automateically generated by a mechanism inspired by the traditional object oriented RPC. No boring action codes, no stoneageish switch-cases, and completely type-safe. May force be with the object oriented programmers!