Skip to content
56 changes: 27 additions & 29 deletions packages/toolkit/src/combineSlices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
UnionToIntersection,
WithOptionalProp,
} from './tsHelpers'
import { emplace } from './utils'

type SliceLike<ReducerPath extends string, State> = {
reducerPath: ReducerPath
Expand Down Expand Up @@ -330,37 +331,34 @@ const stateProxyMap = new WeakMap<object, object>()
const createStateProxy = <State extends object>(
state: State,
reducerMap: Partial<Record<string, Reducer>>
) => {
let proxy = stateProxyMap.get(state)
if (!proxy) {
proxy = new Proxy(state, {
get: (target, prop, receiver) => {
if (prop === ORIGINAL_STATE) return target
const result = Reflect.get(target, prop, receiver)
if (typeof result === 'undefined') {
const reducer = reducerMap[prop.toString()]
if (reducer) {
// ensure action type is random, to prevent reducer treating it differently
const reducerResult = reducer(undefined, { type: nanoid() })
if (typeof reducerResult === 'undefined') {
throw new Error(
`The slice reducer for key "${prop.toString()}" returned undefined when called for selector(). ` +
`If the state passed to the reducer is undefined, you must ` +
`explicitly return the initial state. The initial state may ` +
`not be undefined. If you don't want to set a value for this reducer, ` +
`you can use null instead of undefined.`
)
) =>
emplace(stateProxyMap, state, {
insert: () =>
new Proxy(state, {
get: (target, prop, receiver) => {
if (prop === ORIGINAL_STATE) return target
const result = Reflect.get(target, prop, receiver)
if (typeof result === 'undefined') {
const reducer = reducerMap[prop.toString()]
if (reducer) {
// ensure action type is random, to prevent reducer treating it differently
const reducerResult = reducer(undefined, { type: nanoid() })
if (typeof reducerResult === 'undefined') {
throw new Error(
`The slice reducer for key "${prop.toString()}" returned undefined when called for selector(). ` +
`If the state passed to the reducer is undefined, you must ` +
`explicitly return the initial state. The initial state may ` +
`not be undefined. If you don't want to set a value for this reducer, ` +
`you can use null instead of undefined.`
)
}
return reducerResult
}
return reducerResult
}
}
return result
},
})
stateProxyMap.set(state, proxy)
}
return proxy as State
}
return result
},
}),
}) as State

const original = (state: any) => {
if (!isStateProxy(state)) {
Expand Down
Loading