努力理解如何将可区分的联合类型与减速器一起使用。下面是我的减速器的设置方式。我希望能够将其传递到提供程序组件中,但不断遇到类型错误。
export const enum LoadingState {
idle = "idle",
loading = "loading",
loaded = "loaded",
error = "error",
}
export type SampleState =
| {
status: LoadingState.idle;
}
| {
status: LoadingState.loading;
}
| {
status: LoadingState.loaded;
sampleDetails: SampleDetails;
}
| {
status: LoadingState.error;
error: any;
};
export const INITIAL_STATE: SampleState = {
status: LoadingState.idle,
};
export type Action =
| {
type: "SET_SAMPLE_LOADING_STATE";
payload: { status: LoadingState };
}
| {
type: "SET_SAMPLE";
payload: { sampleDetails: SampleDetails };
};
export const reducer = (state: SampleState, action: Action) => {
switch (action.type) {
case "SET_SAMPLE_LOADING_STATE":
return {
...state,
status: action.payload.status,
};
case "SET_SAMPLE":
return {
...state,
status: LoadingState.loaded,
sampleDetails: action.payload.sampleDetails,
};
default:
return state;
}
};
// Trying to use it here in a provider
const [state, dispatch] = useReducer(
reducer,
INITIAL_STATE
);
但我不断得到:
Argument of type 'SampleState' is not assignable to parameter of type 'never'.
Type '{ status: LoadingState.idle; }' is not assignable to type 'never
我这里的设置有问题吗?如果我从联合中删除其他类型,它会按预期工作。
由于您要将前一个状态与下一个状态合并,因此如果前一个状态为“错误”,并且您使用
"SET_SAMPLE_LOADING_STATE"
操作将其设置为“空闲”,则最终可能会出现无效状态,例如:
{
status: LoadingState.idle,
error: 'something'
}
我认为你可以通过显式地使
reducer
返回 SampleState
来解决这个问题,并让它对你正在设置的状态进行更细粒度的检查,例如:
if (action.payload.status === LoadingState.loaded) {
return {
status: LoadingState.idle,
}
} else if ...