reactjs – React-Redux app中的不变性 – Immutablejs和Typescript Conflict

我们将Immutable.js与TypeScript结合使用,您的意见表示赞赏:

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

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

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

我们还在TypeScript编写了我们的应用程序.

问题是,这两个(Immutable.js和TypeScript)不能很好玩.一旦使用toJS或get或getIn将不可变对象转换为普通JS对象,类型就会更改为any,这会破坏商店和组件之间的类型安全性.

我们尝试了

>演员:

state.users.getIn([‘counts’,visits])作为数字,但我们希望更好的类型安全.

>修复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的想法)

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

但这是垃圾和一个大黑客.
我们得出的结论是,不可能自己修复Immutable.js的类型安全性.*

>香草:

我们试图通过对象传播去vanilla,但是随着数据结构变得复杂,不可变对象的合并变得太复杂并且生成了一个不可读的代码:

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

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

关于记录选项

我们想避免使用记录 – 它在最终浏览器中产生了大量的js代码,只有TypeScript才需要,对于用户来说不是必需的,它是难以维护的,并且最后不会共享完整的,相同的API作为纯JS对象.我在过去的项目中使用它,这是一个非常糟糕的经历.

问题

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

>有人遭受同样的问题吗?有一个很好的解决方案使用Immutable.js和TypeScript?
>任何人都建议更好的库/解决方案,良好的不变性和类型安全性?

最佳答案 更新:

最终,经过一些基准测试和facebook-groups讨论后,我们转换为immer,我们不想回头看.伟大的解决方案 – 打字,简单,对象是原生的,所以不需要学习新的api …我们很高兴.

点赞