Skip to content

Enhancers extending state will not work for all reducers #3773

Closed
@Methuselah96

Description

@Methuselah96

Prior Issues

#1648

What is the current behavior?

The type for enhancers imply that enhancers should be allowed to extend the state. This is problematic for simple states that are just a number or a string because there is no way to extend them while still maintaining the original string or number. If you spread a string or a number, you'll get an empty object back, so if an enhancer tries to extend state, they'll likely end up erasing the user's state.

Steps to Reproduce

function counter(state = 0, action: AnyAction) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}

interface MyStateExt {
  bar: string;
}

function makeEnhancer(): StoreEnhancer<{}, MyStateExt> {
  return (createStore: StoreEnhancerStoreCreator) => <S, A extends Action>(
    reducer: Reducer<S, A>,
    preloadedState?: PreloadedState<S>
  ): Store<S & MyStateExt, A> => {
    const store = createStore(reducer, preloadedState);

    return {
      ...store,
      getState: () => ({ ...store.getState(), bar: "test2" }),
      replaceReducer: (reducer: Reducer<S & MyStateExt, A>) => {
        throw new Error("Not implemented.");
      }
    };
  };
}

const store = createStore(counter, makeEnhancer());
// User expected store.getState() to return their counter number,
// but instead it returns { bar: "test2" } from the enhancer
const state = store.getState();

https://codesandbox.io/s/unruffled-faraday-u502r?fontsize=14&hidenavigation=1&theme=dark

What is the expected behavior?

The types should not allow you to create an enhancer that tries to extend the state because it's not possible to do so if the state is a string or number.

Environment Details

N/A

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions