如何在 TS 中正确输入 `Redux` 增强器?
How to properly type `Redux` enhancer in TS?
我想将 meaingOfFile
属性 添加到我的 redux
状态:
...
type CustomProps =
{
meaingOfFile: number;
}
const ResourceEnhancer: StoreEnhancer<{}, CustomProps> = (createStore) => (reducer, initialState) =>
{
console.log("custom enhancer");
const store = createStore(reducer, initialState);
function getNewState()
{
return {
...store.getState(),
meaingOfFile: 32,
}
}
return { ...store, getState: getNewState};
}
const Store = configureStore({
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(LocalStorageMiddleware),
enhancers: (defaultEnhancers) => [ResourceEnhancer, ...defaultEnhancers],
reducer:{
books: BooksSlice.reducer,
shelfs: ShelfsSlice.reducer,
}
});
但是TS
抛出错误:
TS2322: Type '<S = any, A extends Action<any> = AnyAction>(reducer: Reducer<S, A>, initialState: PreloadedState<S> | undefined) => { getState: () => S & { ...; }; dispatch: Dispatch<...>; subscribe(listener: () => void): Unsubscribe; replaceReducer(nextReducer: Reducer<...>): void; [Symbol.observable](): Observable<...>; }' is not assignable to type 'StoreEnhancerStoreCreator<{}, CustomProps>'.
Call signature return types '{ getState: () => S & { meaingOfFile: number; }; dispatch: Dispatch<A>; subscribe(listener: () => void): Unsubscribe; replaceReducer(nextReducer: Reducer<S & {}, A>): void; [Symbol.observable](): Observable<...>; }' and 'Store<S & CustomProps, A>' are incompatible.
The types of 'replaceReducer' are incompatible between these types.
Type '(nextReducer: Reducer<S & {}, A>) => void' is not assignable to type '(nextReducer: Reducer<S & CustomProps, A>) => void'.
Types of parameters 'nextReducer' and 'nextReducer' are incompatible.
Types of parameters 'state' and 'state' are incompatible.
Type '(S & {}) | undefined' is not assignable to type '(S & CustomProps) | undefined'.
Type 'S & {}' is not assignable to type '(S & CustomProps) | undefined'.
Type 'S & {}' is not assignable to type 'S & CustomProps'.
Property 'meaingOfFile' is missing in type '{}' but required in type 'CustomProps'.
不幸的是,configureStore
类型对 StoreEnhancer
没有真正有效的支持。如果您想在最后添加额外的属性,则必须使用类型转换手动添加这些属性。
在这种情况下,您可以通过使用自定义 reducer 函数包装 rootReducer 来获得相同的结果。
const rootReducer = combineReducers({
books: BooksSlice.reducer,
shelfs: ShelfsSlice.reducer,
}}
const enhancedReducer = (state, action) => {
return {
...rootReducer(state,action),
meaingOfFile: 32,
}
}
const Store = configureStore({
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(LocalStorageMiddleware),
reducer: enhancedReducer
});
我想将 meaingOfFile
属性 添加到我的 redux
状态:
...
type CustomProps =
{
meaingOfFile: number;
}
const ResourceEnhancer: StoreEnhancer<{}, CustomProps> = (createStore) => (reducer, initialState) =>
{
console.log("custom enhancer");
const store = createStore(reducer, initialState);
function getNewState()
{
return {
...store.getState(),
meaingOfFile: 32,
}
}
return { ...store, getState: getNewState};
}
const Store = configureStore({
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(LocalStorageMiddleware),
enhancers: (defaultEnhancers) => [ResourceEnhancer, ...defaultEnhancers],
reducer:{
books: BooksSlice.reducer,
shelfs: ShelfsSlice.reducer,
}
});
但是TS
抛出错误:
TS2322: Type '<S = any, A extends Action<any> = AnyAction>(reducer: Reducer<S, A>, initialState: PreloadedState<S> | undefined) => { getState: () => S & { ...; }; dispatch: Dispatch<...>; subscribe(listener: () => void): Unsubscribe; replaceReducer(nextReducer: Reducer<...>): void; [Symbol.observable](): Observable<...>; }' is not assignable to type 'StoreEnhancerStoreCreator<{}, CustomProps>'.
Call signature return types '{ getState: () => S & { meaingOfFile: number; }; dispatch: Dispatch<A>; subscribe(listener: () => void): Unsubscribe; replaceReducer(nextReducer: Reducer<S & {}, A>): void; [Symbol.observable](): Observable<...>; }' and 'Store<S & CustomProps, A>' are incompatible.
The types of 'replaceReducer' are incompatible between these types.
Type '(nextReducer: Reducer<S & {}, A>) => void' is not assignable to type '(nextReducer: Reducer<S & CustomProps, A>) => void'.
Types of parameters 'nextReducer' and 'nextReducer' are incompatible.
Types of parameters 'state' and 'state' are incompatible.
Type '(S & {}) | undefined' is not assignable to type '(S & CustomProps) | undefined'.
Type 'S & {}' is not assignable to type '(S & CustomProps) | undefined'.
Type 'S & {}' is not assignable to type 'S & CustomProps'.
Property 'meaingOfFile' is missing in type '{}' but required in type 'CustomProps'.
不幸的是,configureStore
类型对 StoreEnhancer
没有真正有效的支持。如果您想在最后添加额外的属性,则必须使用类型转换手动添加这些属性。
在这种情况下,您可以通过使用自定义 reducer 函数包装 rootReducer 来获得相同的结果。
const rootReducer = combineReducers({
books: BooksSlice.reducer,
shelfs: ShelfsSlice.reducer,
}}
const enhancedReducer = (state, action) => {
return {
...rootReducer(state,action),
meaingOfFile: 32,
}
}
const Store = configureStore({
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(LocalStorageMiddleware),
reducer: enhancedReducer
});