SuperAPI AI 工具集

fp-immutable

编程与开发

查看项目

更新于 10-16 02:01

技能介绍

用途

fp-immutable 是一份面向 TypeScript 开发者的实用不可变(immutability)模式参考,属于 fp-ts-skills 技能集。它通过大量代码示例,说明如何在不修改原始数据的前提下更新数组、对象和深层嵌套结构,并讨论何时直接修改(mutation)是合理甚至更优的选择。

主要能力

资料围绕以下主题展开:

  • 不可变性的价值:共享状态导致意外行为、调试时保留历史状态、撤销/重做、React/Redux 中基于 === 的变化检测、避免副作用。
  • 展开运算符模式:数组的末尾添加、开头添加、按索引插入、按索引删除、按值删除、按索引更新、替换匹配项;对象的更新属性、添加属性、删除属性(解构 + 展开)、合并对象、条件更新。
  • 嵌套数据更新:展示逐层展开的写法,并给出一个类似 lens 的 updateIn 辅助函数,通过路径数组递归更新。
  • 常见任务:切换列表项布尔值、按 ID 更新数组项、合并默认值、克隆并修改(含深拷贝数组与对象)。
  • const 的真相:const 只阻止重新赋值,不阻止修改;readonly 类型提供编译期不可变;Object.freeze() 提供运行时浅冻结。
  • readonly 类型:只读数组、只读对象、递归的 DeepReadonly 类型。
  • 何时可以修改:函数内部局部变量、构建局部结果、性能关键代码、一次性构建对象、局部数组填充。
  • Immer:当展开嵌套过于痛苦时,使用 produce 以“看似修改”的写法获得不可变结果;以及配合 React 的 useImmer。
  • 快速参考表:汇总常用任务的不可变写法。

使用方式

资料以代码片段形式呈现,可直接参考其中的模式编写 TypeScript 代码。示例包括:

  • 数组操作:[...items, 4]、[0, ...items]、[...items.slice(0, 1), 99, ...items.slice(1)]、items.filter(x => x !== 2)、items.map((x, i) => i === 1 ? 99 : x)。
  • 对象操作:{ ...user, age: 31 }、const { role, ...withoutRole } = user、{ ...defaults, ...prefs }、{ ...user, ...(shouldUpdate && { age: 31 }) }。
  • 嵌套更新:逐层展开,或使用 updateIn(state, ['user', 'profile', 'settings', 'theme'], () => 'dark')。
  • 常见任务函数:toggleTodo、updateUser、createConfig、cloneOrder。
  • 类型:readonly T[]、Readonly<{...}>、DeepReadonly<T>。
  • Immer:import { produce } from 'immer',以及 import { useImmer } from 'use-immer'。

适用场景

  • 使用 React/Redux 等需要不可变状态更新的前端项目。
  • 需要保留历史状态以支持调试、撤销/重做的应用。
  • 希望避免共享状态副作用、提升代码可推理性的 TypeScript 代码库。
  • 需要处理深层嵌套对象更新的场景,可选用 Immer 简化。

限制

  • 资料为模式参考,未提供安装命令、包版本或完整项目配置。
  • Object.freeze() 是浅冻结,嵌套对象仍可被修改。
  • const 不提供不可变性,仅阻止重新赋值。
  • 性能关键代码中,不可变写法可能带来 GC 压力,资料建议先做性能分析。
  • 未提供关于 Immer 的安装方式、版本要求或与具体框架集成的完整步骤。