TypeScript中Redux Toolkit createSlice reducer访问state.entities报错的解决
解决Redux Toolkit中TypeScript的"Object is possibly 'undefined'"错误
问题场景
在使用Redux Toolkit的createEntityAdapter和createSlice编写代码时,执行state.entities[key].isVisible = false这一行时,TypeScript抛出以下错误:
Object is possibly 'undefined'.ts(2532) (property) entities: WritableDraft<Dictionary<Question>>
相关代码实现:
const questionsAdapter = createEntityAdapter<Question>({ selectId: (question) => question.key, }); const defaultValue: Question[] = []; questions.map((question) => { defaultValue.push(question as Question); }); const initialState = questionsAdapter.getInitialState(); const questionSlice = createSlice({ name: "questions", initialState, reducers: { fetchQuestions(state) { questionsAdapter.upsertMany(state, defaultValue); }, hideQuestion(state, action: PayloadAction<{ key: EntityId }>) { const { key } = action.payload; state.entities[key].isVisible = false; }, } });
解决方法
以下是几种可行的解决方案,按推荐程度排序:
使用
createEntityAdapter提供的updateOne方法(推荐)
既然已经用了实体适配器,直接调用它的更新方法是最符合Redux Toolkit规范且类型安全的方式,适配器会自动处理实体的存在性判断:hideQuestion(state, action: PayloadAction<{ key: EntityId }>) { const { key } = action.payload; questionsAdapter.updateOne(state, { id: key, changes: { isVisible: false } }); }先判断实体是否存在
手动添加条件判断,确保访问属性前实体已存在,这是最严谨的类型安全写法:hideQuestion(state, action: PayloadAction<{ key: EntityId }>) { const { key } = action.payload; const targetQuestion = state.entities[key]; if (targetQuestion) { targetQuestion.isVisible = false; } }使用非空断言操作符(!)
如果你能100%确定传入的key对应的实体一定存在于state.entities中,可以用非空断言告诉TypeScript忽略undefined的可能性,但这种方式有运行时风险,需谨慎使用:hideQuestion(state, action: PayloadAction<{ key: EntityId }>) { const { key } = action.payload; state.entities[key]!.isVisible = false; }
内容的提问来源于stack exchange,提问作者Mahesh
相关产品推荐
相关产品推荐

