Repository: reduxjs/redux-toolkit (ts)

Issue:
Initial createReducer state is not frozen
Immer auto-freezes state when processed in a case reducer. However, we currently do not freeze the _initial_ state.  This means that it _is_ possible to mutate the initial state before any actions are dispatched.  Not sure if the mutation checker picks up on it or not.

Another issue is that I'm looking at updating the immutability and serialization checks to skip past frozen values for speed. If the initial state isn't frozen, we don't get the benefit there. Now, it's also likely that the initial state is almost empty so it won't take long to scan those values anyway, but I can't see a reason to _not_ freeze the initial state.

Fortunately, it looks like it's trivial to do this by adding:

```js
const frozenInitialState = createNextState(initialState, draft => {})
```

and using the frozen state instead.

Pull request description:
Freeze initial state by passing through Immer
This PR:

- Updates `createReducer` to freeze the initial state by running it through Immer

Fixes #939 

Patch:
diff --git a/src/createReducer.ts b/src/createReducer.ts
index d06c71f8..db07d7e6 100644
--- a/src/createReducer.ts
+++ b/src/createReducer.ts
@@ -199,7 +199,9 @@ export function createReducer<S>(
       ? executeReducerBuilderCallback(mapOrBuilderCallback)
       : [mapOrBuilderCallback, actionMatchers, defaultCaseReducer]
 
-  return function(state = initialState, action): S {
+  const frozenInitialState = createNextState(initialState, () => {})
+
+  return function(state = frozenInitialState, action): S {
     let caseReducers = [
       actionsMap[action.type],
       ...finalActionMatchers


Test patch:
diff --git a/src/createReducer.test.ts b/src/createReducer.test.ts
index b2e7c0ab..660d6447 100644
--- a/src/createReducer.test.ts
+++ b/src/createReducer.test.ts
@@ -90,6 +90,16 @@ describe('createReducer', () => {
         'Cannot add property text, object is not extensible'
       )
     })
+
+    test('Freezes initial state', () => {
+      const initialState = [{ text: 'Buy milk' }]
+      const todosReducer = createReducer(initialState, {})
+
+      const mutateStateOutsideReducer = () => (initialState[0].text = 'edited')
+      expect(mutateStateOutsideReducer).toThrowError(
+        /Cannot assign to read only property/
+      )
+    })
   })
 
   describe('given pure reducers with immutable updates', () => {