Reputation: 14438
I'm getting a Typescript error that an object I'm using from Redux is possibly undefined, even though I don't say it's type can be undefined or set it to undefined anywhere.
/redux/globalSettings/actions.ts
import { ADD_GLOBAL_SETTINGS } from '../../config/actions';
import { AddGlobalSettingsAction } from './types';
import GlobalSettings from '../../typings/contentful/GlobalSettings';
export const addGlobalSettings = (payload: GlobalSettings): AddGlobalSettingsAction => ({
type: ADD_GLOBAL_SETTINGS,
payload,
});
/redux/globalSettings/reducers.ts
import { ADD_GLOBAL_SETTINGS } from '../../config/actions';
import { GlobalSettingsAction, GlobalSettingsState } from './types';
export default (
state: GlobalSettingsState,
action: GlobalSettingsAction,
): GlobalSettingsState => {
switch (action.type) {
case ADD_GLOBAL_SETTINGS:
return { ...action.payload };
default:
return state;
}
}
/redux/globalSettings/types.ts
import { ADD_GLOBAL_SETTINGS } from '../../config/actions';
import GlobalSettings from '../../typings/contentful/GlobalSettings';
export type GlobalSettingsState = GlobalSettings;
export interface AddGlobalSettingsAction {
payload: GlobalSettings;
type: typeof ADD_GLOBAL_SETTINGS;
}
export type GlobalSettingsAction = AddGlobalSettingsAction;
/redux/reducer.ts
import { combineReducers } from 'redux';
import globalSettings from './globalSettings/reducers';
const rootReducer = combineReducers({
globalSettings,
});
export type StoreState = ReturnType<typeof rootReducer>;
export default rootReducer;
/redux/index.ts
import { applyMiddleware, createStore } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly';
import rootReducer, { StoreState } from './reducer';
export const initialiseStore = (
initialState: StoreState,
) => createStore(
rootReducer,
initialState,
composeWithDevTools(applyMiddleware()),
);
I use this in my NextJS project by using next-redux-wrapper
NPM package (a React HOC) on the export of my _app.js
page like so:
export default withRedux(initialiseStore)(Page);
I get an error in /redux/reducer.ts of: Type 'undefined' is not assignable to type 'GlobalSettings'
.
If I use the globalSettings
redux state on one of my pages, accessing globalSettings.fields.navigationLinks
creates another Typescript error that globalSettings
might be undefined.
Driving me crazy, what have I done wrong here?
Upvotes: 1
Views: 3007
Reputation: 59
I had an issue similar to this when I added extraReducers
to a pre-existing reducers
dict (using redux-toolkit
). All of my reducers
previously fine had TypeScript errors around either
WritableDraft<WritableDraft<MySlice>>
and/or
Type 'undefined' is not assignable to type 'WritableDraft<MySlice>'
It turns out one of my reducers
was returning undefined instead of state
(redux-toolkit
uses immer
so I guess it may work despite return undefined
).
Returning state
fixed it.
Upvotes: 0
Reputation: 11848
The error
I get an error in /redux/reducer.ts of: Type 'undefined' is not assignable to type 'GlobalSettings'
relates to how you defined reducer
It should be
const initalState: GlobalSettingsState = {/* valid inital state */};
export default (
state: GlobalSettingsState | undefined = initalState,
action: GlobalSettingsAction,
): GlobalSettingsState => {
switch (action.type) {
case ADD_GLOBAL_SETTINGS:
return { ...action.payload };
default:
return state;
}
}
Reducer can be called with state set to undefined (to initialize state). So state
argument should has undefined
as possible value.
Upvotes: 3