【问题标题】:Immutability in React-Redux app - Immutablejs and Typescript ConflictReact-Redux 应用程序中的不变性 - Immutablejs 和 Typescript 冲突
【发布时间】:2018-02-06 15:12:22
【问题描述】:

Immutable.jsTypeScript 的组合存在问题,感谢您的意见:

在过去的一年里,我们正在开发一个 react-redux 应用程序。

根据几乎所有最佳实践、常识和redux docs 中的建议,我们的商店数据是不可变的。

正如上面的 redux 文档中所建议的那样,在许多大型项目中使用,并且由于许多样板正在实施,我们正在使用 Immutable.js

我们还在TypeScript 中编写我们的应用程序。

问题是,这两个(Immutable.jsTypeScript)不能很好地发挥作用。一旦使用toJSgetgetIn 将不可变对象转换为普通JS 对象,类型将更改为any,这破坏了存储和组件之间的类型安全。

我们试过了

  1. 演员:

state.users.getIn(['counts', visits]) as number 但我们希望有更好的类型安全性。

  1. 修复Immutable.js 的输入:

我们也尝试自己输入,有时甚至达到了

interface ImmutableMap<T> {
 get<K extends keyof T>(name: K): T[K];
 set<S>(k: string, o: S): ImmutableMap<T & S>;
 getIn(searchKeyPath: any[], notSetValue?: any): T;
}

(来自here的想法)

假设 getIn 只被 toJS 调用并且总是返回一个 JS 对象(我们有时在 higher-order-component 中这样做 - 但这是另一回事)。

但这是废话和大黑客。 我们得出的结论是,我们自己无法修复 Immutable.js 的类型安全性。*

  1. 原版:

我们尝试过普通的对象传播,但随着数据结构变得复杂,不可变对象的合并变得过于复杂并生成了不可读的代码:

{
    ...state,
    profiles: {
      ...state.profiles,
      [id]: {
        ...state.profiles[id],
        meta: {
          ...state.profiles[id].meta,
          [sub]: payload,
        },
      },
    },

我们最终构建了另一个需要维护的 Immutable.js 库 - 太多代码无法支持。

关于记录选项

我们要避免使用record——它会在终端浏览器中产生一大堆js代码,只有TypeScript需要,用户不需要,维护起来很麻烦,最后不与纯 JS 对象共享完整的、相同的 API。我在过去的项目中使用它,这是一次非常糟糕的经历。

问题

我的问题是针对创建/使用复杂 React-Redux 应用程序的人:

  1. 有人遇到同样的问题吗?有一个很好的解决方案来使用Immutable.jsTypeScript
  2. 有人推荐了更好的库/解决方案,以获得良好的不变性和类型安全性吗?

【问题讨论】:

  • 我同意 Immutable.js 不能很好地与 TypeScript 配合使用。我个人使用您的选项 3(“香草”),但它有时会有点混乱。我尽量不要把我的状态嵌套得太深,所以在大多数情况下它运作良好。您可以尝试的一个可能的库是 Immer,我还没有使用它,但它看起来特别适合 TypeScript(定义包含在库中)。
  • 考虑使用immer

标签: reactjs typescript redux immutability immutable.js


【解决方案1】:

更新:

最终,经过一些基准测试和 facebook-groups 讨论,我们转换为 immer,我们不想回头。很好的解决方案 - 类型化、简单、对象是原生的,因此无需学习新的 API……我们很高兴。

【讨论】:

    猜你喜欢
    • 2016-02-22
    • 2019-04-09
    • 2016-11-17
    • 1970-01-01
    • 2019-11-02
    • 2017-08-05
    • 1970-01-01
    • 2020-08-20
    • 1970-01-01
    相关资源
    最近更新 更多