All Projects → lttb → typed-actions

lttb / typed-actions

Licence: MIT license
Type-safe redux-actions

Programming Languages

javascript
184084 projects - #8 most used programming language
typescript
32286 projects

Projects that are alternatives of or similar to typed-actions

redux-tools
💪 Maintaining large Redux applications with ease.
Stars: ✭ 34 (-20.93%)
Mutual labels:  redux-observable, redux-actions
react-ts-sample
sample tech stack with react and typescript
Stars: ✭ 26 (-39.53%)
Mutual labels:  redux-observable
Cra Boilerplate
Up to date: This project is an Create React App - v2.1.1 boilerplate with integration of Redux, React Router, Redux thunk & Reactstrap(Bootstrap v4)
Stars: ✭ 87 (+102.33%)
Mutual labels:  redux-observable
Rex Tils
Type safe utils for redux actions, epics, effects, react/preact default props, various type guards and TypeScript utils, React util components
Stars: ✭ 245 (+469.77%)
Mutual labels:  redux-observable
Types First Ui
An opinionated framework for building long-lived, maintainable UI codebases
Stars: ✭ 114 (+165.12%)
Mutual labels:  redux-observable
ts-action-operators
TypeScript action operators for NgRx and redux-observable
Stars: ✭ 34 (-20.93%)
Mutual labels:  redux-observable
Redux Epics Decorator
Dumb decorators for redux & redux-observable & react-redux & redux-actions
Stars: ✭ 60 (+39.53%)
Mutual labels:  redux-observable
ngx-redux-core
The modern redux integration for Angular 6+
Stars: ✭ 32 (-25.58%)
Mutual labels:  redux-actions
fetch-action-creator
Fetches using standardized, four-part asynchronous actions for redux-thunk.
Stars: ✭ 28 (-34.88%)
Mutual labels:  redux-actions
Stuhome
📱 An iOS client for https://bbs.uestc.edu.cn/ written in react-native, redux and redux-observable.
Stars: ✭ 241 (+460.47%)
Mutual labels:  redux-observable
React Redux Firebase
Redux bindings for Firebase. Includes React Hooks and Higher Order Components.
Stars: ✭ 2,492 (+5695.35%)
Mutual labels:  redux-observable
Redux Most
Most.js based middleware for Redux. Handle async actions with monadic streams & reactive programming.
Stars: ✭ 137 (+218.6%)
Mutual labels:  redux-observable
redux-thunk-actions
Action creator for redux-thunk that handles sync and async functions.
Stars: ✭ 63 (+46.51%)
Mutual labels:  redux-actions
Oh My Fullstack
🚀 Full stack web application skeleton (Next.js, Redux, RxJS, Immutable, Express)
Stars: ✭ 99 (+130.23%)
Mutual labels:  redux-observable
ts-react-boilerplate
A very opinionated (React/TypeScript/Redux/etc) frontend boilerplate
Stars: ✭ 43 (+0%)
Mutual labels:  redux-observable
Feeble
A React/Redux Architecture
Stars: ✭ 72 (+67.44%)
Mutual labels:  redux-observable
Rxjs Websockets
A very flexible and simple websocket library for rxjs
Stars: ✭ 248 (+476.74%)
Mutual labels:  redux-observable
mst-effect
💫 Designed to be used with MobX-State-Tree to create asynchronous actions using RxJS.
Stars: ✭ 19 (-55.81%)
Mutual labels:  redux-observable
hot-redux-chassis
Modern React/Redux/RxJS application using all the latest and greatest stuff from the community 🔥
Stars: ✭ 20 (-53.49%)
Mutual labels:  redux-observable
React Redux Observable Typescript Sample
A sample application for React + redux-observable + TypeScript
Stars: ✭ 147 (+241.86%)
Mutual labels:  redux-observable

typed-actions

Travis branch npm version npm license

Some Types and Utils (based on redux-actions way) to create type-safe actions, reducers, and epics with auto-inferred types.

Main points:

  • 100% Flow coverage for the redux-side with minimum typings (auto-inferred types) and less boilerplate
  • Safe types and functions, which help to reduce risks for Type mistakes
  • Accurate Type-errors handling
  • Deep immutable Type (Frozen) for actions and redux state
  • Immer support

Installation

npm install typed-actions

Usage

You can get some examples here with explanations.

Actions

Actions are compatible with Flux Standard Action

  • action(payload, ?meta) produces {type, payload} | {type, payload, meta}
  • error(payload, ?meta) produces {type, payload, error: true} | {type, payload, meta, error: true}
  • empty() produces {type}
import {createActions, action, empty} from 'typed-actions'
import type {EntityId} from '../types';

/**
 * Declare Action Types as constants and export them
 */
export const UPDATE = '@namespace/UPDATE'
export const UPDATE_FULFILLED = '@namespace/UPDATE_FULFILLED'
export const UPDATE_FAILED = '@namespace/UPDATE_FAILED'

/**
 * Create Actions Collection
 */
const actions = createActions({
    /**
     * {type: UPDATE}
     */
    [UPDATE]: empty,
    /**
     * {type: UPDATE_FULFILLED, payload: EntityId[]}
     */
    [UPDATE_FULFILLED]: (x: EntityId[]) => action(x),
    /**
     * {type: UPDATE_FAILED, payload: EntityId, meta: {sync: true}}
     */
    [UPDATE_FAILED]: (x: EntityId) => action(x, {sync: true}),
})

/**
 * Export Action Creators
 */
export const {
    [UPDATE]: update,
    [UPDATE_FULFILLED]: updateFulfilled,
    [UPDATE_FAILED]: updateFailed,
} = actions

/**
 * Export Collection Type
 */
export type Actions = typeof actions

You might find this declaration style more readable:

let actions

export const {
    [UPDATE]: update,
    [UPDATE_FULFILLED]: updateFulfilled,
    [UPDATE_FAILED]: updateFailed,
} = actions = createActions({
    [UPDATE]: empty,
    [UPDATE_FULFILLED]: (x: EntityId[]) => action(x)
    [UPDATE_FAILED]: (x: EntityId) => action(x, {sync: true}),
})

export type Actions = typeof actions

Reducers

import {handleActions, type Handlers, type Frozen} from 'typed-actions';
import type {EntityId} from '../types';

/**
 * Import action types with Actions Collection Type
 */
import {
    type Actions,
    UPDATE,
    UPDATE_FULFILLED,
    UPDATE_FAILED,
} from './actions';

/**
 * Declare State for the reducer
 */
export type State = {
    data: EntityId[],
    status: 'done' | 'pending' | 'failed',
};

/**
 * Use Handlers Type for the type-casting.
 * This way functions will get right arguments Types
 */
export default handleActions(({
    /**
     * No need to point the State Type in arguments,
     * it would be auto-inferred Deep Immutable Type of State
     */
    [UPDATE]: state => ({
        ...state,
        status: 'pending',
    }),

    /**
     * The second argument (action) will also have the right type
     * {type: UPDATE_FULFILLED, payload: EntityId[]}
     */
    [UPDATE_FULFILLED]: (state, {payload}) => ({
        ...state,
        data: payload,
        status: 'done',
    }),

    [UPDATE_FAILED]: state => ({
        ...state,
        status: 'failed',
    }),
}: Handlers<State, Actions>));

Immer

You can use immer for immutable state modifying.

Note that handler accepts 3 arguments: draft state (for changes), action and current state.

import { type Handlers, handleActions } from 'typed-actions/immer'
import type {EntityId} from '../types';

import {
    type Actions,
    UPDATE,
    UPDATE_FULFILLED,
    UPDATE_FAILED,
} from './actions';

export type State = {
    data: EntityId[],
    status: 'done' | 'pending' | 'failed',
};

export default handleActions(({
    [UPDATE]: state => {
        state.status = 'pending'
    },

    [UPDATE_FULFILLED]: (state, {payload}) => {
        state.data = payload
        state.status = 'done'
    },

    [UPDATE_FAILED]: state => {
        state.status = 'failed'
    },
}: Handlers<State, Actions>));

Epics

If you're using redux-observable, this Epic Type could be useful.

import type {Epic} from 'typed-actions/redux-observable';

import {
    type Actions,
    UPDATE_FULFILLED,
    anotherOneAction,
} from './actions';

import {type State} from './reducers';

export const updateEpic: Epic<State, Actions> = action$ => action$
    .ofType(UPDATE_FULFILLED)
    /**
     * No need to add types here, action would be the right Type out of the box
     */
    .map(action => anotherOneAction(action.payload));

export const unionEpic: Epic<State, Actions> = action$ => action$
    .ofType(UPDATE, UPDATE_FULFILLED)
    /**
     * {type: UPDATE} | {type: UPDATE_FULFILLED, payload: EntityId[]}
     */
    .map(action => {
        if (action.type === UPDATE_FULFILLED) {
            /**
             * Type Refinement will work as well
             *
             * {type: UPDATE_FULFILLED, payload: EntityId[]}
             */
            console.log(action.payload)
        }
    });

Just to note, if you're using dependencies in epics, you can pass its type in as the third argument.

type Dependencies = {api: () => void}

export const epic: Epic<State, Actions, Dependencies> = action$ => action$

The recommended way is to redeclare your own Epic type with custom dependencies and use it, like:

// types.js
import type {Epic} from 'typed-actions/redux-observable'

type Dependencies = {api: () => void}

export type Epic<S, A, D = Dependencies> = Epic<S, A, D>

// epics.js
import type {Epic} from './types'

export const epic: Epic<State, Actions> = action$ => action$
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].