我对Typescript React App中Redux的类型保存实现有一些疑问。
我已经在Reducer上完成了设置和类型检查,还使用了react-redux中的useTypedSelector。在这里,我在案例的Reducer语句中只有一件事是松散的类型检查,但这并不是那么成问题。
我的Redux商店设置:
// --------------------------------------- REDUX STORE ---------------------------------------
interface ITimePreset {
session: number;
break: number;
}
const UPDATE_TIMEPRESET = 'UPDATE_TIMEPRESET';
const INCREMENT_TIMEPRESET = 'INCREMENT_TIMEPRESET';
const DECREMENT_TIMEPRESET = 'DECREMENT_TIMEPRESET';
const BREAK = 'break';
const SESSION = 'session';
type Item = typeof BREAK | typeof SESSION;
interface IUpdateTimepresetAction {
type: typeof UPDATE_TIMEPRESET;
payload: {
value: number;
item: Item;
};
}
interface IIncrementTimepresetAction {
type: typeof INCREMENT_TIMEPRESET;
payload: Item;
}
interface IDecrementTimepresetAction {
type: typeof DECREMENT_TIMEPRESET;
payload: Item;
}
type TimePresetActionTypes = IUpdateTimepresetAction | IIncrementTimepresetAction | IDecrementTimepresetAction;
const initialState: ITimePreset = {
session: 25,
break: 5,
};
const timePresetReducer = (state: ITimePreset = initialState, action: TimePresetActionTypes): ITimePreset => {
switch (action.type) {
case UPDATE_TIMEPRESET:
return {
...state,
[action.payload.item]: action.payload.value,
};
case INCREMENT_TIMEPRESET:
return {
...state,
[action.payload]: state[action.payload] + 1,
};
case DECREMENT_TIMEPRESET:
return {
...state,
[action.payload]: state[action.payload] - 1,
};
default:
return state;
}
};
const rootReducer = combineReducers({
timePreset: timePresetReducer,
});
type RootState = ReturnType<typeof rootReducer>;
const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector;
const store = createStore(rootReducer);
使用useTypedSelector进行良好的类型检查非常好:
const timePreset: ITimePreset = useTypedSelector(state => state.timePreset);
但是对于useDispatch,我没有找到用于类型检查的解决方案:
const dispatch = useDispatch();
// This is the correct one:
dispatch({ type: DECREMENT_TIMEPRESET, payload: element });
// Wrong one with no error
dispatch({ type: 'Whaaat', payload: 9 });
有没有一种方法可以对useDispatch参数进行类型检查? 您是否对实施Redux Store有其他建议(一些最佳实践)->这是我的第一个示例。
答案 0 :(得分:1)
一些对您有所帮助的事情。
type ActionType = 'UPDATE_TIMEPRESET' | 'INCREMENT_TIMEPRESET' | 'DECREMENT_TIMEPRESET';
当然,模块的特定类型可能很重要,您不需要将它们放在一个地方,例如
import SomethingActionType from 'someModule';
import Something2ActionType from 'someModule2';
type ActionType = SomethingActionType | Something2ActionType;
我们需要对Action
的外观有一个一般的定义。示例类型:
type Action<P> = {
type: ActionType,
payload: P
}
我们的Action
是类型构造函数,我们现在可以定义特定类型,例如Action<string>
或Action<UserRequest>
下一步是定义ActionCreator类型。 ActionCreator只是返回有效Action的简单函数。
type ActionCreator<P> = (p: P) => Action<P>;
const incrementTimePreset: ActionCreator<Item> = payload => ({
type: 'INCREMENT_TIMEPRESET' // type safe as it goes from ActionType union
payload
})
const decrementTimePreset: ActionCreator<Item> = payload => ({
type: 'DECREMENT_TIMEPRESET' // type safe as it goes from ActionType union
payload
})
现在,我们将使用动作创建器,而不是手动使用useDispatch
和一些对象常量。
dispatch(decrementTimePreset(item))
const useSafeDispatch = () => {
const dispatch = useDispatch();
return <P>(action: Action<P>) => dispatch(action);
}
// using
const dispatch = useSafeDispatch();
dispatch(decrementTimePreset(item)); // only proper action structure is allowed