我已经使用 React.js 完成了几个项目。其中一些使用了 Flux,一些使用了 Redux,还有一些只是使用 Context 的普通 React 应用程序。
我真的很喜欢 Redux 使用函数式模式的方式。但是,开发人员无意中改变状态的可能性很大。在寻找解决方案时,基本上只有一个答案——Immutable.js。老实说,我讨厌这个图书馆。它完全改变了你使用 JavaScript 的方式。此外,它必须在整个应用程序中实现,否则当某些对象是纯 JS 而某些对象是不可变结构时,您最终会遇到奇怪的错误。或者您开始使用 .toJS()
,这再次非常糟糕。
最近,我的一位同事建议使用 TypeScript。除了类型安全之外,它还有一个有趣的特性——您可以定义自己的数据结构,这些数据结构的所有字段都标记为 readonly
。这样的结构本质上是不可变的。
我不是 Immutable.js 或 TypeScript 方面的专家。然而,在 Redux 存储中拥有不可变数据结构而不使用 Immutable.js 的 promise 似乎好得令人难以置信。 TypeScript 的 readonly
是 Immutable.js 的合适替代品吗?还是有什么隐藏的问题?
最佳答案
虽然 TypeScript 的 readonly
修饰符确实只存在于设计类型中,不会影响运行时代码,但整个类型系统都是如此。也就是说,在运行时没有什么能阻止您将数字分配给string
类型的变量。所以这个答案有点转移注意力...如果您在设计时收到警告,您正在尝试改变标记为 const
或 readonly
的内容,那么这将可能消除了对大量运行时检查的需要。
但是readonly
不足的一个主要原因。有一个 outstanding issue对于 readonly
,目前(从 TS3.4 开始),仅在它们的 readonly
属性上不同的类型是可以相互分配的。这让您可以轻松突破任何属性的保护性 readonly
外壳并弄乱内部结构:
type Person = { name: string, age: number }
type ReadonlyPerson = Readonly<Person>;
const readonlyPerson: ReadonlyPerson = { name: "Peter Pan", age: 12 };
readonlyPerson.age = 40; // error, "I won't grow up!"
const writablePerson: Person = readonlyPerson; // no error?!?!
writablePerson.age = 40; // no error! Get a job, Peter.
console.log(readonlyPerson.age); // 40
这对 readonly
来说非常糟糕。在这个问题得到解决之前,您可能会发现自己同意以前的问题提交者谁有 originally named the issue “只读修饰符是个笑话”🤡。
即使这个问题得到解决,readonly
也可能无法涵盖所有用例。您还需要遍历库(甚至标准库)中的所有接口(interface)和类型,并删除改变状态的方法。因此,所有使用 Array
的都需要更改为 ReadonlyArray
,所有使用 Map
的都需要更改为 ReadonlyMap
等。一旦你这样做了,你就有了一种相当类型安全的方式来表示不变性。但这是很多工作。
无论如何,希望对您有所帮助;祝你好运!
关于reactjs - TypeScript 的 `readonly` 能否完全替代 Immutable.js?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55905801/