TypeScript FSA Reducers

1.2.2 · active · verified Sun Apr 19

TypeScript FSA Reducers provides a fluent, typesafe API for defining Redux reducers. It builds on `typescript-fsa` to streamline reducer creation by removing common boilerplate such as `if-else` chains for action type checking and manual extraction of payloads from actions. Instead, it offers a method-chaining approach with dedicated handlers for specific action creators. The current stable version is 1.2.2. While there isn't a strictly defined release cadence, the library has demonstrated consistent updates and a commitment to stability, notably reaching version 1.0.0. Its key differentiators include the fluent builder pattern (`.case()`, `.default()`, `.withHandling()`, `.build()`), strong type inference for state and payloads, and direct integration with `typescript-fsa`'s action creators, making reducer logic concise and highly maintainable in TypeScript Redux applications.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates defining a typesafe Redux reducer using `reducerWithInitialState`, handling different action types with `.case()`, adding a default handler, and calling `.build()` to finalize the reducer. It also shows basic reducer usage.

import actionCreatorFactory from 'typescript-fsa';
import { reducerWithInitialState } from 'typescript-fsa-reducers';

const actionCreator = actionCreatorFactory();

interface State {
    name: string;
    balance: number;
    isFrozen: boolean;
}

const INITIAL_STATE: State = {
    name: 'Untitled',
    balance: 0,
    isFrozen: false,
};

const setName = actionCreator<string>('SET_NAME');
const addBalance = actionCreator<number>('ADD_BALANCE');
const setIsFrozen = actionCreator<boolean>('SET_IS_FROZEN');

const myReducer = reducerWithInitialState(INITIAL_STATE)
    .case(setName, (state, name) => ({ ...state, name }))
    .case(addBalance, (state, amount) => ({
        ...state,
        balance: state.balance + amount,
    }))
    .case(setIsFrozen, (state, isFrozen) => ({ ...state, isFrozen }))
    .default((state, action) => {
        // Handle any unhandled actions or simply return the state.
        console.log(`Unhandled action: ${action.type}`);
        return state;
    })
    .build(); // Don't forget to call .build() to get the final reducer function

// Example usage (typically with Redux store)
let currentState = myReducer(undefined, { type: '@@INIT' }); // Initial state
console.log('Initial state:', currentState); // { name: 'Untitled', balance: 0, isFrozen: false }

currentState = myReducer(currentState, setName('Alice'));
console.log('After setName:', currentState); // { name: 'Alice', balance: 0, isFrozen: false }

currentState = myReducer(currentState, addBalance(100));
console.log('After addBalance:', currentState); // { name: 'Alice', balance: 100, isFrozen: false }

currentState = myReducer(currentState, { type: 'UNKNOWN_ACTION' });
console.log('After UNKNOWN_ACTION:', currentState); // { name: 'Alice', balance: 100, isFrozen: false } (and console log for unhandled action)

view raw JSON →