如何使用 Typescript 在 Redux reducer 函数中实现详尽的 switch 语句?如何处理 Redux 的内部 @@redux 动作
How to implement an exhaustive switch statement inside a Redux reducer function using Typescript? How to handle Redux's internal @@redux actions
我试图找到一个明确的答案,但还没有找到。
SO 上有一个问题可以回答如何实施详尽的 switch
语句:
答案是:
编写一个函数,将 never
作为参数,returns never
并在调用任何内容时抛出异常。
function assertUnreachable(x: never): never {
throw new Error("Didn't expect to get here");
}
并在您的 default
案例中使用它:
switch (action.type) {
case "A": {
...
}
case "B": {
...
}
default: {
return assertUnreachable(action); // CAN'T USE action.type HERE BECAUSE action WILL BE never AND action.type WILL BE any
}
}
但我不能在 reducer
中这样使用它。它会检查我的 reducer 操作的详尽性,但会在运行时抛出异常,因为 Redux 会用自己的内部操作调用它,例如:
@@redux/INITh.b.0.x.q.h // THIS IS THE action.type
@@redux/PROBE_UNKNOWN_ACTIONe.7.b.o.p // THIS IS THE action.type
那么在 reducer 中处理 switch
语句穷举的理想方法是什么?
我在 Note on TypeScript's exhaustive type checks in scope of Redux's reducer 中找到了一个巧妙的解决方案。解决办法是:
- 编译时触发错误
- 不要在运行时抛出错误
function endReducer<T>(state: T, action: never): T {
return state;
}
function reducer(state: State, action: Actions) {
switch (action.type) {
case ...
default:
return endReducer(state, action);
}
}
这里的正确答案是根本不用担心这个。
即使使用那个 switch 语句,你的 reducer 也会被其他动作调用。因此,尝试限制确切的操作集并没有多大帮助。
更好的方法是使用 our official Redux Toolkit package 中的 createSlice
API,并让它定义您希望在该特定切片中处理的操作。
我试图找到一个明确的答案,但还没有找到。
SO 上有一个问题可以回答如何实施详尽的 switch
语句:
答案是:
编写一个函数,将 never
作为参数,returns never
并在调用任何内容时抛出异常。
function assertUnreachable(x: never): never {
throw new Error("Didn't expect to get here");
}
并在您的 default
案例中使用它:
switch (action.type) {
case "A": {
...
}
case "B": {
...
}
default: {
return assertUnreachable(action); // CAN'T USE action.type HERE BECAUSE action WILL BE never AND action.type WILL BE any
}
}
但我不能在 reducer
中这样使用它。它会检查我的 reducer 操作的详尽性,但会在运行时抛出异常,因为 Redux 会用自己的内部操作调用它,例如:
@@redux/INITh.b.0.x.q.h // THIS IS THE action.type
@@redux/PROBE_UNKNOWN_ACTIONe.7.b.o.p // THIS IS THE action.type
那么在 reducer 中处理 switch
语句穷举的理想方法是什么?
我在 Note on TypeScript's exhaustive type checks in scope of Redux's reducer 中找到了一个巧妙的解决方案。解决办法是:
- 编译时触发错误
- 不要在运行时抛出错误
function endReducer<T>(state: T, action: never): T {
return state;
}
function reducer(state: State, action: Actions) {
switch (action.type) {
case ...
default:
return endReducer(state, action);
}
}
这里的正确答案是根本不用担心这个。
即使使用那个 switch 语句,你的 reducer 也会被其他动作调用。因此,尝试限制确切的操作集并没有多大帮助。
更好的方法是使用 our official Redux Toolkit package 中的 createSlice
API,并让它定义您希望在该特定切片中处理的操作。