Redux Toolkit createSlice状态支持null值的TypeScript类型报错解决
问题根因
你遇到的报错是createSlice的自动类型推断和真实业务类型需求不匹配导致的,对应报错信息为:
Type 'SalesOrder | null' is not assignable to type 'void | SalesOrder | WritableDraft
'.
Type 'null' is not assignable to type 'void | SalesOrder | WritableDraft'.ts(2322)
createSlice的状态类型完全根据传入的initialState自动推导,你当前的代码存在两处类型误导:
- 你写的
initialState = {} as Order是通过强制类型断言,把一个空对象伪装成了非空的Order类型,TS完全感知不到你的状态需要支持存储null值,只会默认当前切片的状态永远是非空的Order(对应的不可变草稿类型是WritableDraft<Order>) - 因为状态被推断为非空类型,TS要求reducer的返回值只能是
void | Order | WritableDraft<Order>,不允许出现null值,和你setOrder里返回Order | null的逻辑产生了类型冲突。你悬停看到的reducer错误类型签名,本质就是TS把State类型错判为非空草稿类型的直观体现。
具体修复方案
不需要修改reducer的业务逻辑,只需要从类型层面明确告诉TS「这个切片的状态允许存储null值」即可,步骤如下:
- 第一步:显式定义订单切片的状态类型,把null纳入允许范围
// 定义符合业务要求的状态类型:订单数据 或者 空值 type OrderSliceState = Order | null; - 第二步:调整初始值,去掉强制类型断言的误导
空的Order对象本身就不符合初始状态的空值逻辑,直接把初始值设为null即可,和类型定义匹配:const initialState: OrderSliceState = null; - 第三步:给
createSlice传入明确的State泛型参数,修正类型推断的偏差
不需要写复杂的类型断言,直接把刚才定义的状态类型作为泛型传入,TS就会按照你的真实类型约束做校验:
调整完成后,TS会识别到状态类型是import { createSlice, PayloadAction } from '@reduxjs/toolkit'; type OrderSliceState = Order | null; const initialState: OrderSliceState = null; const orderSlice = createSlice<OrderSliceState>({ name: 'order', initialState, reducers: { // 原有的业务逻辑完全不需要改动 setOrder: (_state, { payload }: PayloadAction<Order | null>) => payload, }, }); // 正常导出action和reducer即可 export const { setOrder } = orderSlice.actions; export default orderSlice.reducer;Order | null,会自动允许reducer返回包含null的合法值,之前的类型报错会直接消失。
注意事项
- 不要为了消掉报错把
setOrder的payload类型改成非空值,这会直接违背你需要支持设置null的业务需求 - 尽量避免用
xxx as Type的强制断言强行改写类型,显式定义状态类型的写法,后续维护的时候不容易出现类型偏移的问题
内容的提问来源于stack exchange,提问作者Mindaugas Nakrošis
相关产品推荐
相关产品推荐

