Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

immer-reducer

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

immer-reducer - npm Package Compare versions

Comparing version 0.1.0 to 0.1.1

17

lib/immer-reducer.d.ts
import { Draft } from "immer";
/** get function arguments as tuple type */
declare type ArgumentsType<T> = T extends (...args: infer V) => any ? V : never;
/** Get union of function property names */
declare type FunctionPropertyNames<T> = {
[K in keyof T]: T[K] extends Function ? K : never;
}[keyof T];
/** Pick only methods from object */
declare type Methods<T> = Pick<T, FunctionPropertyNames<T>>;
/** flatten functions in an object to their return values */
declare type FlattenToReturnTypes<T extends {

@@ -12,9 +16,13 @@ [key: string]: () => any;

};
/** get union of object value types */
declare type ObjectValueTypes<T> = T[keyof T];
/** get union of object method return types */
declare type ReturnTypeUnion<T extends {
[key: string]: () => any;
}> = ObjectValueTypes<FlattenToReturnTypes<T>>;
/** type constrant for the ImmerReducer class */
export interface ImmerReducerClass {
new (...args: any[]): ImmerReducer<any>;
}
/** get state type from a ImmerReducer subclass */
declare type ImmerReducerState<T> = T extends {

@@ -25,2 +33,7 @@ prototype: {

} ? V : never;
/** generate reducer function type form the ImmerReducer class */
interface ImmerReducerFunction<T extends ImmerReducerClass> {
(state: ImmerReducerState<T> | undefined, action: ReturnTypeUnion<ActionCreators<T>>): ImmerReducerState<T> | undefined;
}
/** generate ActionCreators types from the ImmerReducer class */
export declare type ActionCreators<ClassActions extends ImmerReducerClass> = {

@@ -32,2 +45,3 @@ [K in keyof Methods<InstanceType<ClassActions>>]: (...args: ArgumentsType<InstanceType<ClassActions>[K]>) => {

};
/** The actual ImmerReducer class */
export declare class ImmerReducer<T> {

@@ -39,6 +53,3 @@ readonly state: T;

export declare function createActionCreators<T extends ImmerReducerClass>(immerReducerClass: T): ActionCreators<T>;
interface ImmerReducerFunction<T extends ImmerReducerClass> {
(state: ImmerReducerState<T> | undefined, action: ReturnTypeUnion<ActionCreators<T>>): ImmerReducerState<T> | undefined;
}
export declare function createReducerFunction<T extends ImmerReducerClass>(immerReducerClass: T): ImmerReducerFunction<T>;
export {};

3

lib/immer-reducer.js

@@ -8,2 +8,3 @@ "use strict";

var PREFIX = "IMMER_REDUCER";
/** The actual ImmerReducer class */
var ImmerReducer = /** @class */ (function () {

@@ -41,3 +42,3 @@ function ImmerReducer(draftState, state) {

});
return actionCreators;
return actionCreators; // typed in the function signature
}

@@ -44,0 +45,0 @@ exports.createActionCreators = createActionCreators;

{
"name": "immer-reducer",
"version": "0.1.0",
"version": "0.1.1",
"description": "",

@@ -5,0 +5,0 @@ "main": "lib/immer-reducer.js",

@@ -5,4 +5,6 @@ # Immer Reducer

Create Redux reducers using [Immer](https://github.com/mweststrate/immer)! [Typescript friendly](#100-type-safety-with-typescript).
Create Redux reducers using [Immer](https://github.com/mweststrate/immer)!
Typescript [friendly](#100-type-safety-with-typescript) too.
## Install

@@ -17,8 +19,11 @@

```js
import {ImmerReducer, createActionCreators} from "immer-reducer";
import {ImmerReducer} from "immer-reducer";
export class MyImmerReducer extends ImmerReducer {
// each method becomes a reducer
// The class represents the classic switch-case reducer
class MyImmerReducer extends ImmerReducer {
// each method becomes an Action Creator
setFirstName(firstName) {
// State update are simple as assigning a value to the state property thanks to Immer
// State updates are simple as assigning a value to
// the draftState property thanks to Immer
this.draftState.firstName = firstName;

@@ -31,3 +36,3 @@ }

// You can combine reducers too
// You can combine methods to a single Action Creator
setName(firstName, lastName) {

@@ -45,7 +50,7 @@ this.setFirstName(firstName);

export const ActionCreators = createActionCreators(MyImmerReducer);
export const reducerFunction = createReducerFunction(MyImmerReducer);
const ActionCreators = createActionCreators(MyImmerReducer);
const reducerFunction = createReducerFunction(MyImmerReducer);
```
and create a Redux store
and create the Redux store

@@ -86,6 +91,6 @@ ```js

So the method names becomes Redux Action Types and the method arguments
becomes the action payload. The reducer function will then match these
So the method names become the Redux Action Types and the method arguments
become the action payloads. The reducer function will then match these
actions against the class and calls the approciate methods with the payload
spread to the arguments. But do note that the action format is not part of
array spread to the arguments. But do note that the action format is not part of
the public API so don't write any code relying on it. The actions are handled

@@ -101,3 +106,6 @@ by the generated reducer function.

specifically Typescript usage in mind because I was unable to find any other
libraries that make Redux usage both boilerplate free and 100% type safe.
libraries that make Redux usage both boilerplate free and 100% type safe. To
be honest it was no easy feat. Pretty advanced Typescript sorcery was
required and so this library requires Typescript 3.1 or later. But the end
results is really simple for the end user.

@@ -108,9 +116,12 @@ The Typescript usage does not differ that much from the Javascript usage.

```ts
const initialState = {
firstName: "",
lastName: "",
};
interface State {
// The state can be defined as read only
readonly firstName: string;
readonly lastName: string;
}
class MyImmerReducer extends ImmerReducer<typeof initialState> {
class MyImmerReducer extends ImmerReducer<State> {
setFirstName(firstName: string) {
// draftState has the State type but the readonly
// flags are removed here to allow type safe mutation
this.draftState.firstName = firstName;

@@ -125,3 +136,3 @@ }

The generated ActionsTypes object now respects the types used in the class
The generated `ActionsTypes` object now respects the types used in the class

@@ -141,2 +152,7 @@ ```ts

const initialState: State = {
firstName: "",
lastName: "",
};
reducer(initialState, ActionCreators.setFirstName("Charlie")); // OK

@@ -147,4 +163,6 @@ reducer(initialState, {type: "WAT"}); // Type error

## Type Safe connect()?
If you enjoy this then also checkout
[redux-render-prop](https://github.com/epeli/redux-render-prop) for type safe
`connect()` alternative.

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc