什么是 io-ts 以及为什么需要它?
io-ts 是一个用于 TypeScript 的库,它解决了该语言开发中最棘手的问题之一:静态类型(编译时)与实际数据(运行时)之间的差异。TypeScript 是一个出色的工具,但其类型系统仅在开发阶段起作用。当您的应用程序运行时,所有类型都会被擦除。如果您从外部 API、网站表单、localStorage 或任何其他不受编译器控制的源获取数据,您无法确保数据符合声明的类型。
这时,运行时验证就派上了用场。io-ts 允许您一次定义数据模式,然后将其用于两个目的:
- 静态类型(编译时): TypeScript 根据您的模式推断类型,在编写代码时确保安全性。
- 运行时验证: io-ts 检查实际数据是否符合您的模式,并返回成功结果或详细的错误信息。
该库基于编解码器(codecs)的概念。编解码器是一个对象,它知道如何解码(验证和转换)原始数据为 TypeScript 类型,以及如何编码(序列化)该类型。这使得 io-ts 不仅是一个强大的验证工具,也是一个安全的数据序列化/反序列化工具。
安装
io-ts 是一个用于 Node.js 和浏览器生态系统的库,因此通过 npm(或 yarn)安装。请注意,io-ts 需要 fp-ts 作为对等依赖项,因为它使用了诸如 Either 和 Option 等函数式概念。
npm install io-ts fp-ts或者,如果您使用 yarn:
yarn add io-ts fp-ts安装后,您可以将库导入到您的项目中:
import * as t from 'io-ts';import { isRight, isLeft } from 'fp-ts/Either';快速入门:第一个示例
让我们从一个简单的示例开始。假设我们期望一个包含 name(字符串)和 age(数字)字段的用户对象。使用 io-ts 定义模式,并尝试验证一些数据。
import * as t from 'io-ts';import { isRight, isLeft } from 'fp-ts/Either';
// 1. 定义模式(编解码器)const User = t.type({ name: t.string, age: t.number,});
// 2. 安全获取类型的函数type User = t.TypeOf<typeof User>;
// 3. 待验证的数据const validData = { name: 'Alice', age: 30 };const invalidData = { name: 'Bob', age: '二十' }; // age 是字符串,不是数字
// 4. 验证const result1 = User.decode(validData);const result2 = User.decode(invalidData);
console.log(isRight(result1)); // trueconsole.log(isLeft(result2)); // true
// 5. 提取数据(如果验证通过)if (isRight(result1)) { const user: User = result1.right; console.log(user.name); // Alice}
// 6. 处理错误if (isLeft(result2)) { console.error('验证错误:', result2.left); // 将输出错误列表,例如: // [ { value: '二十', context: [...], message: '提供给 : { name: string, age: number }/age: number 的无效值 "二十"' } ]}在这个示例中,我们看到了关键模式:decode 返回来自 fp-ts 库的 Either<Errors, A>。Either 是一个容器,可以包含错误(左侧类型)或成功值(右侧类型)。我们使用 isRight 和 isLeft 函数检查结果。
io-ts 的主要方法和函数
io-ts 提供