Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/marckassay/zustand-redux-extends-type
A zustand redux extended type for actions
https://github.com/marckassay/zustand-redux-extends-type
redux typescript typings zustand
Last synced: about 1 month ago
JSON representation
A zustand redux extended type for actions
- Host: GitHub
- URL: https://github.com/marckassay/zustand-redux-extends-type
- Owner: marckassay
- License: mit
- Created: 2022-10-18T23:00:44.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2022-10-19T20:06:23.000Z (over 2 years ago)
- Last Synced: 2024-12-14T22:11:28.348Z (about 2 months ago)
- Topics: redux, typescript, typings, zustand
- Language: TypeScript
- Homepage:
- Size: 29.4 MB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# zustand-redux-extends-type
To be used with [zustand's redux middleware](https://github.com/pmndrs/zustand/blob/main/docs/guides/flux-inspired-practice.md). To install:
```
npm add zustand-redux-extends-type -D # or yarn add zustand-redux-extends-type -D
```Leveraging typings (`ReduxExtends` and `FeatureEventActions`) as below eliminates the need to use any type assertions in reducers. It also enforces only valid values for properties when `dispatch` is being typed out.
```typescript
import type { ReduxExtends } from "zustand-redux-extends-type";type FeatureEventActions = {
grumpiness: {
increase: number;
decrease: number;
reset: undefined;
};
happiness: {
"show all": User[];
level: "low" | "sort of" | "high";
};
};const useGrumpyStore = create(
redux(
(
state: { count: number; level: "low" | "sort of" | "high" },
{ type, payload }: ReduxExtends
) => {
switch (type) {
case "grumpiness/increase":
return { ...state, count: state.count + payload };
case "grumpiness/decrease":
return { ...state, count: state.count - payload };
case "grumpiness/reset":
return { ...state, count: 0 };
//removed happiness cases for brevity
default:
return state;
}
},
{ count: 0, level: "high" }
)
);const dispatch = useGrumpyStore((state) => state.dispatch);
dispatch({ type: "grumpiness/decrease", payload: 1 });
```The structure of this map type, `FeatureEventActions`, is premised on [Redux's recommendation for actions](https://redux.js.org/tutorials/fundamentals/part-3-state-actions-reducers#what-youve-learned):
"_The type field should be a readable string, and is usually written as 'feature/eventName'_"
For this example, 'grumpiness' and 'happiness' are features with event names of 'increase' and 'show all' respectively. Each event name is typed for what will be its `payload` type. Any `action` object of `ReduxExtends`, either as a parameter of `reducer` or `dispatch`, has its `type` property constrained to what will be parsed by TypeScript. This will also dictate the `payload` type.