@@ -88,22 +88,21 @@ export interface Slice<
8888 /**
8989 * Get localised slice selectors (expects to be called with *just* the slice's state as the first parameter)
9090 */
91- getSelectors ( this : this ) : Id < SliceDefinedSelectors < State , Selectors , State > >
91+ getSelectors ( ) : Id < SliceDefinedSelectors < State , Selectors , State > >
9292
9393 /**
9494 * Get globalised slice selectors (`selectState` callback is expected to receive first parameter and return slice state)
9595 */
9696 getSelectors < RootState > (
97- this : this,
98- selectState : ( this : this, rootState : RootState ) => State
97+ selectState : ( rootState : RootState ) => State
9998 ) : Id < SliceDefinedSelectors < State , Selectors , RootState > >
10099
101100 /**
102101 * Selectors that assume the slice's state is `rootState[slice.reducerPath]` (which is usually the case)
103102 *
104103 * Equivalent to `slice.getSelectors((state: RootState) => state[slice.reducerPath])`.
105104 */
106- selectors : Id <
105+ get selectors ( ) : Id <
107106 SliceDefinedSelectors < State , Selectors , { [ K in ReducerPath ] : State } >
108107 >
109108
@@ -126,7 +125,7 @@ export interface Slice<
126125 *
127126 * Will throw an error if slice is not found.
128127 */
129- selectSlice ( this : this , state : { [ K in ReducerPath ] : State } ) : State
128+ selectSlice ( state : { [ K in ReducerPath ] : State } ) : State
130129}
131130
132131/**
@@ -153,15 +152,15 @@ interface InjectedSlice<
153152 * Get globalised slice selectors (`selectState` callback is expected to receive first parameter and return slice state)
154153 */
155154 getSelectors < RootState > (
156- selectState : ( this : this , rootState : RootState ) => State | undefined
155+ selectState : ( rootState : RootState ) => State | undefined
157156 ) : Id < SliceDefinedSelectors < State , Selectors , RootState > >
158157
159158 /**
160159 * Selectors that assume the slice's state is `rootState[slice.name]` (which is usually the case)
161160 *
162161 * Equivalent to `slice.getSelectors((state: RootState) => state[slice.name])`.
163162 */
164- selectors : Id <
163+ get selectors ( ) : Id <
165164 SliceDefinedSelectors <
166165 State ,
167166 Selectors ,
@@ -740,8 +739,8 @@ export function buildCreateSlice({ creators }: BuildCreateSliceConfig = {}) {
740739
741740 const selectSelf = ( state : State ) = > state
742741
743- const injectedSelectorCache = new WeakMap <
744- Slice < State , CaseReducers , Name , ReducerPath , Selectors > ,
742+ const injectedSelectorCache = new Map <
743+ boolean ,
745744 WeakMap <
746745 ( rootState : any ) => State | undefined ,
747746 Record < string , ( rootState : any ) => any >
@@ -750,23 +749,42 @@ export function buildCreateSlice({ creators }: BuildCreateSliceConfig = {}) {
750749
751750 let _reducer : ReducerWithInitialState < State >
752751
753- const slice : Slice < State , CaseReducers , Name , ReducerPath , Selectors > = {
754- name,
755- reducerPath,
756- reducer ( state , action ) {
757- if ( ! _reducer ) _reducer = buildReducer ( )
752+ function reducer ( state : State | undefined , action : UnknownAction ) {
753+ if ( ! _reducer ) _reducer = buildReducer ( )
758754
759- return _reducer ( state , action )
760- } ,
761- actions : context . actionCreators as any ,
762- caseReducers : context . sliceCaseReducersByName as any ,
763- getInitialState ( ) {
764- if ( ! _reducer ) _reducer = buildReducer ( )
755+ return _reducer ( state , action )
756+ }
765757
766- return _reducer . getInitialState ( )
767- } ,
768- getSelectors ( selectState : ( rootState : any ) => State = selectSelf ) {
769- const selectorCache = emplace ( injectedSelectorCache , this , {
758+ function getInitialState ( ) {
759+ if ( ! _reducer ) _reducer = buildReducer ( )
760+
761+ return _reducer . getInitialState ( )
762+ }
763+
764+ function makeSelectorProps < CurrentReducerPath extends string = ReducerPath > (
765+ reducerPath : CurrentReducerPath ,
766+ injected = false
767+ ) : Pick <
768+ Slice < State , CaseReducers , Name , CurrentReducerPath , Selectors > ,
769+ 'getSelectors' | 'selectors' | 'selectSlice' | 'reducerPath'
770+ > {
771+ function selectSlice ( state : { [ K in CurrentReducerPath ] : State } ) {
772+ let sliceState = state [ reducerPath ]
773+ if ( typeof sliceState === 'undefined' ) {
774+ if ( injected ) {
775+ sliceState = getInitialState ( )
776+ } else if ( process . env . NODE_ENV !== 'production' ) {
777+ throw new Error (
778+ 'selectSlice returned undefined for an uninjected slice reducer'
779+ )
780+ }
781+ }
782+ return sliceState
783+ }
784+ function getSelectors (
785+ selectState : ( rootState : any ) => State = selectSelf
786+ ) {
787+ const selectorCache = emplace ( injectedSelectorCache , injected , {
770788 insert : ( ) => new WeakMap ( ) ,
771789 } )
772790
@@ -777,39 +795,39 @@ export function buildCreateSlice({ creators }: BuildCreateSliceConfig = {}) {
777795 options . selectors ?? { }
778796 ) ) {
779797 map [ name ] = wrapSelector (
780- this ,
781798 selector ,
782799 selectState ,
783- this !== slice
800+ getInitialState ,
801+ injected
784802 )
785803 }
786804 return map
787805 } ,
788806 } ) as any
789- } ,
790- selectSlice ( state ) {
791- let sliceState = state [ this . reducerPath ]
792- if ( typeof sliceState === 'undefined' ) {
793- // check if injectInto has been called
794- if ( this !== slice ) {
795- sliceState = this . getInitialState ( )
796- } else if ( process . env . NODE_ENV !== 'production' ) {
797- throw new Error (
798- 'selectSlice returned undefined for an uninjected slice reducer'
799- )
800- }
801- }
802- return sliceState
803- } ,
804- get selectors ( ) {
805- return this . getSelectors ( this . selectSlice )
806- } ,
807+ }
808+ return {
809+ reducerPath,
810+ getSelectors ,
811+ get selectors ( ) {
812+ return getSelectors ( selectSlice )
813+ } ,
814+ selectSlice ,
815+ }
816+ }
817+
818+ const slice : Slice < State , CaseReducers , Name , ReducerPath , Selectors > = {
819+ name ,
820+ reducer ,
821+ actions : context . actionCreators as any ,
822+ caseReducers : context . sliceCaseReducersByName as any ,
823+ getInitialState ,
824+ ... makeSelectorProps ( reducerPath ) ,
807825 injectInto ( injectable , { reducerPath : pathOpt , ...config } = { } ) {
808- const reducerPath = pathOpt ?? this . reducerPath
809- injectable . inject ( { reducerPath, reducer : this . reducer } , config )
826+ const newReducerPath = pathOpt ?? reducerPath
827+ injectable . inject ( { reducerPath : newReducerPath , reducer } , config )
810828 return {
811- ...this ,
812- reducerPath ,
829+ ...slice ,
830+ ... makeSelectorProps ( newReducerPath , true ) ,
813831 } as any
814832 } ,
815833 }
@@ -818,16 +836,16 @@ export function buildCreateSlice({ creators }: BuildCreateSliceConfig = {}) {
818836}
819837
820838function wrapSelector < State , NewState , S extends Selector < State > > (
821- slice : Slice ,
822839 selector : S ,
823840 selectState : Selector < NewState , State > ,
841+ getInitialState : ( ) => State ,
824842 injected ?: boolean
825843) {
826844 function wrapper ( rootState : NewState , ...args : any [ ] ) {
827- let sliceState = selectState . call ( slice , rootState )
845+ let sliceState = selectState ( rootState )
828846 if ( typeof sliceState === 'undefined' ) {
829847 if ( injected ) {
830- sliceState = slice . getInitialState ( )
848+ sliceState = getInitialState ( )
831849 } else if ( process . env . NODE_ENV !== 'production' ) {
832850 throw new Error (
833851 'selectState returned undefined for an uninjected slice reducer'
0 commit comments