本页面介绍了如何有效地使用 TypeScript 和 Zustand 进行类型安全的响应式状态管理。内容涵盖了从基础用法到高级模式,重点介绍了 Zustand 的 TypeScript 特有功能和类型定义。
Zustand 在设计时就考虑了 TypeScript,在保持其极简 API 的同时,提供了强大的类型和推断能力。本指南将帮助您利用 TypeScript 的静态类型来创建更健壮、更易于维护的 Zustand 存储。
来源: docs/guides/typescript.md6-22
当使用 TypeScript 和 Zustand 时,您需要定义存储的状态类型,并通过带有柯里化语法的 create 函数来提供它,即 create<T>()(...)(注意额外的括号)。
柯里化模式允许 TypeScript 在您注释状态类型时,能够正确地推断和检查类型。此方法是必要的,因为状态泛型是不可变的(出现在输入和输出位置)。
来源: docs/guides/typescript.md6-22 docs/guides/typescript.md23-57
combine 中间件一起使用或者,您可以使用 combine 中间件,它可以自动推断状态类型
此方法不需要显式定义状态类型,因为它是从初始状态对象推断出来的。
来源: docs/guides/typescript.md136-147 docs/guides/typescript.md148-162
如果您需要从存储中提取状态类型以在其他地方使用,Zustand 提供了 ExtractState 类型辅助函数
这在您需要将存储的状态类型用于其他组件或函数时特别有用。
来源: docs/guides/typescript.md164-177
在使用中间件和 TypeScript 时,通常可以直接使用它们,无需特殊的类型注解。
但是,重要的是要正确放置中间件的顺序,特别是要确保像 devtools 这样会修改 setState 的中间件,作为最外层的中间件使用。
来源: docs/guides/typescript.md179-227
Zustand 使用一种名为“高阶变异器”的高级 TypeScript 技术来处理修改存储类型的中间件。这使得类型安全的中间件能够在运行时向存储添加属性。
来源: docs/guides/typescript.md228-248
对于不更改存储类型的中间件
此类型在扩展功能的同时保留了存储类型。
来源: docs/guides/typescript.md287-335
对于向存储添加属性的中间件
这种更复杂的类型允许中间件向存储对象本身添加类型化的属性。
来源: docs/guides/typescript.md336-387
Zustand 为其内置中间件提供了类型定义
| 中间件 | 变异器类型 |
|---|---|
devtools | ["zustand/devtools", never] |
persist | ["zustand/persist", PersistedState] |
immer | ["zustand/immer", never] |
subscribeWithSelector | ["zustand/subscribeWithSelector", never] |
redux | ["zustand/redux", Action] |
combine | 无变异器(不修改存储) |
来源: docs/guides/typescript.md534-543
切片模式允许您将存储分割成模块化的部分,同时保持类型安全。
此模式可为大型应用程序实现可组合、类型安全的响应式状态管理。
来源: docs/guides/typescript.md414-478
对于原生存储(不使用 React 绑定),您可以创建类型安全的绑定 Hooks。
或者使用更通用的 createBoundedUseStore 模式。
来源: docs/guides/typescript.md482-532
Zustand 保持与广泛的 TypeScript 版本兼容。该库定期使用从 4.5.5 到最新版本的多个 TypeScript 版本进行测试,确保广泛的兼容性。
来源: .github/workflows/test-old-typescript.yml1-56
在使用带 TypeScript 的 persist 中间件时,您可以指定存储类型。
对于与非 JSON 可序列化类型(如 Map 和 Set)兼容的自定义存储,您需要创建一个自定义存储实现。
来源: docs/integrations/persisting-store-data.md38-61 docs/integrations/persisting-store-data.md762-833
replace 标志当在 setState 中使用动态 replace 标志时,您可能会遇到类型问题。使用 Parameters 实用类型作为解决方法。
来源: docs/guides/typescript.md250-282
由于 TypeScript 需要知道您的状态中的 Map 或 Set 何时发生变化,因此在更新它们时,您应该创建新的实例。
这遵循了 React 的不可变更新最佳实践。