如何从打字稿 useReducer 钩子安全地断言某个状态?

时间:2021-06-04 09:49:30

标签: reactjs typescript react-hooks

假设我们有以下状态及其 reducer 动作

type User = {
    id: number
}

type LoginState = {
    user?: User,
    isLoggingIn: boolean,
    isLoggedIn: boolean,
    error?: Error
}

type LoginActions =
    | { type: 'START_LOGGING_IN' }
    | { type: 'SUCCESSFUL_LOG_IN', user: User }
    | { type: 'ERROR', error: Error }
    | { type: 'START_LOGGING_IN' }

如果我想从我的所有应用程序中使用这个状态,我肯定需要一些反应上下文解决方案。我不希望此问题使用任何外部依赖项。

然而,在 some fsharp learning 之后,这种方法导致不可能的状态成为可能。例如,如果我们在减速器中出错,状态 isLoggedIn 可能会出错。

解决方案是使 LoginState 成为可区分的联合类型,但就我测试过的 useReducer 的打字稿类型而言,强制我将所有属性都包含在一个类型中,就像示例中一样。

那么,这个问题一般是怎么解决的呢?我知道我描述的示例是标准方法,但是,每当使用登录状态时,我都必须在每个地方处理用户不存在,这是我不想要的。我想要这个问题的最类型安全的解决方案,所以也请不要使用 type assertions

如果我所做的某些断言有误,请纠正我,我对前端的东西很困惑:S

谢谢!

1 个答案:

答案 0 :(得分:0)

最安全的方法是将 LoginState 定义为仅包含有效 reducer 状态的 discriminated union。这使您能够定义仅处理它们设计用于的那些联合的组成类型的函数。

TS playground

尽管通常很忙,而且大多数时候开发人员对您的问题中定义的 LoginState 类型非常满意。