typescript - 类型 'AsyncThunkAction' 中缺少属性 'type',但在类型 'AnyAction' 中是必需的
代码:
import { configureStore, ConfigureStoreOptions, createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import logger from 'redux-logger';
interface fetchUserResponse {
name: string;
}
const fetchUser = createAsyncThunk<fetchUserResponse, void>('users/fetchUser', async () => {
return { name: 'teresa teng' };
});
const usersSlice = createSlice({
name: 'users',
initialState: { name: '' },
reducers: {},
extraReducers: (builder) => {
builder.addCase(fetchUser.fulfilled, (state, action) => {
state.name = action.payload.name;
});
},
});
interface UserState {
name: string;
}
interface AppState {
user: UserState;
}
const storeConfig: ConfigureStoreOptions<AppState> = {
reducer: {
user: usersSlice.reducer,
},
};
if (process.env.NODE_ENV !== 'production') {
storeConfig.middleware = (getDefaultMiddlewares) => getDefaultMiddlewares().concat(logger);
}
const store = configureStore(storeConfig);
store.dispatch(fetchUser()); // TSC throws error
当我尝试分派 fetchUser() 动作时,TSC 会抛出以下错误。
类型为 'AsyncThunkAction
' 的参数不能赋值给类型为 'AnyAction' 的参数。类型 'AsyncThunkAction ' 中缺少属性 'type',而 'AnyAction' 类型中该属性是必需的。ts(2345)
需要传递哪些通用参数给通用类型 ConfigureStoreOptions 才能通过 TSC 类型检查。
软件包版本:
"@reduxjs/toolkit": "^1.5.0",
"typescript": "^4.1.2"
更新
如果我不使用ConfigureStoreOptions,当我尝试动态设置storeConfig的middleware属性时,我会得到以下错误。
属性 'middleware' 在类型 '{ reducer: { user: Reducer<{ name: string; }, AnyAction>; }; }' 上不存在。ts(2339)
答案#1
正如 @phry 所说,如果你直接调用 configureStore,可以完全跳过使用 ConfigureStoreOptions 类型:
const store = configureStore({
reducer: {
user: usersSlice.reducer
}
});
在你的 storeConfig: ConfigureStoreOptions<AppState> 类型中缺少的部分是中间件类型的声明。当前类型不包括 thunk 或任何其他中间件,所以你无法分发 AsyncThunkAction。你需要调整你的 storeConfig 类型以支持 thunk。你可以通过设置第三个泛型类型参数 M 来实现这一点。
这是类型的定义方式:
ConfigureStoreOptions<S = any, A extends Action<any> = AnyAction, M extends Middlewares<S> = Middlewares<S>>
你需要直接从 "redux-thunk" 导入 ThunkMiddleware 类型,因为 "@reduxjs/toolkit" 并没有重新导出它。
import { configureStore, ConfigureStoreOptions } from "@reduxjs/toolkit";
import {ThunkMiddleware} from "redux-thunk";
const storeConfig: ConfigureStoreOptions<AppState, AnyAction, [ThunkMiddleware<AppState, AnyAction>]> = {
reducer: {
user: usersSlice.reducer
}
};
const store = configureStore(storeConfig);
store.dispatch(fetchUser());
你可以这样做,并且它可以工作,但老实说,当你可以直接将选项传递给 configureStore 并获得所有类型推断时,这样做有点傻。
答案#2
redux-toolkit 维护者在此 👋
ConfigureStoreOptions 真的是一个你绝不应该手动使用的类型——它是通过实际调用 configureStore 来推断的。(我真的不知道如何手动为它设置类型,而我已经完成了当前 RTK 类型的大部分工作)
这实际上是我第一次见有人这样做。有什么特别迫切的原因让你一定要这样做吗?也许我可以提供一个替代方案。
看到你更新的代码后,我真的建议你做类似这样的事情
const store = configureStore({
reducer: {
user: usersSlice.reducer,
},
middleware(getDefaultMiddlewares) {
if (process.env.NODE_ENV !== 'production') {
return getDefaultMiddlewares().concat(logger);
}
else {
return getDefaultMiddlewares()
}
}
});
你可以在这个游乐场看到它的运行情况
