# @amritk/validation 中文文档

规范地址：https://npmcn.com/package/%40amritk/validation/

版本：0\.6\.1
npm 元数据更新时间：2026-10-22T18:54:16.863Z
中文译文更新时间：2026-11-06T01:35:30.574Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40amritk/validation
原文对照：https://npmcn.com/package/%40amritk/validation/?lang=original
项目主页：https://github.com/amritk/mjst/tree/main/packages/validation#readme
源码仓库：https://github.com/amritk/mjst

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：681 kB，94 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=20
- 运行依赖：2 个
- 首次发布：2026-09-22T07:29:16.782Z
- 最新版本发布：2026-10-22T18:54:16.478Z
- 近 30 天下载量：59097（2026-10-06 至 2026-11-04，npm 官方下载统计）
- 已发布版本数：9（近 12 个月 9 个）

## 中文简介

一个发电机表面超过Mjst的种类,验证器,胁迫器,修理器和剖析器.

## 安装

```sh
npm install @amritk/validation
```

也可以使用：`pnpm add @amritk/validation`、`yarn add @amritk/validation`、`bun add @amritk/validation`

## README

# @ amritk/ 验证

**一个发电机表面超过Mjst的种类,守卫,验证者,胁迫者,修理者和剖析器.**

* * *

## 概览

`@amritk/validation` 是前门 由于一个JSON Schema(2020-12草案),它喷出 包含任意运行时间切入点的一组一致类型脚本文件 要求——从赤裸裸的型号,通过布林警卫和完整的出错报告,到 胁迫者,修理者 和全剖析器.

在下面,这是 **两个** 发电机引擎,不是一台:验证器、强制器和 修理机引擎,以及解析器和类型引擎。 他们分别作为 `@amritk/generate-validators` 财务报告和审定财务报表 `@amritk/generate-parsers` 直到此软件包 吸收了它们 保留它们都是故意的 他们真的不同 生成值模式的代码: 以 检查它,而且速度是它的多倍;验证员保存通行证 分开,因此可以报告什么是错的。 把它们折叠成一个发射器 这意味着放弃其中之一财产.

使得一个输出目录成为可能的是,两者都获得 TypeScript 类型 从同 `@amritk/helpers/generate-type-definition`,所以该类型被宣布 **一次** 输出中的每一个功能都涉及到它.

* * *

## 安装

```bash
bun add @amritk/validation
```

* * *

## 使用量

```typescript
import { generate } from '@amritk/validation'
import type { JSONSchema } from 'json-schema-typed/draft-2020-12'

const schema: JSONSchema = {
  type: 'object',
  properties: {
    retries: { type: 'integer', minimum: 0, maximum: 10, default: 3 },
    name: { type: 'string', minLength: 3 },
  },
  required: ['retries', 'name'],
}

const files = await generate(schema, 'Config', {
  modes: ['types', 'guard', 'validate', 'coerce', 'repair', 'parse'],
})

for (const file of files) await Bun.write(`./generated/${file.filename}`, file.content)
```

* * *

## 模式

每种模式对 _这会对我的文件造成多大影响 有人告诉我_。它们会编曲: 要求多个功能,然后您会得到多个功能 一种类型, 每一个判断一个价值 它以同样的判断 `validateX`, (中文(简体) ), 因此,对于一个文件是否有效,没有两人可以持不同意见.

| 模式 | 函数 | 返回值 | 告诉你 | 停下来 |
| :-- | :-- | :-- | :-- | --: |
| `types` | —— 说 | —— 说 | —— 说 | —— 说 |
| `guard` | `isX(input): input is X` | —— 说 | 布尔 | 第一个问题 |
| `validate` | `validateX(input)` | —— 说 | 每个错误 | 结束 |
| `check` | `checkX(input)` | —— 说 | 第一个错误 | 第一个问题 |
| `coerce` | `coerceX(input)` | 被胁迫 | 每个错误 | 结束 |
| `repair` | `repairX(input)` | 已修复 | 维修 **财务报告和审定财务报表** 错误 | 结束 |
| `parse` | `parseX(input)` | 已修复 | 无 | 从不失败 |
| `parseStrict` | `parseX(input)` | 给定的 | 丢出第一个 | 第一个问题 |

**只验证、 快速失败或找到每个错误 .** `guard` 失败的快取: 它在第一件事上停止错误, 没有构建错误对象, 它在无效时 投入比报告便宜得多. `validate` 是另一半: 每一个 错误,每个都带有 JSON 指针,关键词拒绝了该值,并且 关键词本身的值. 到达 `guard` 当答案是树枝 `validate` 当一个人类或API客户端必须被告知如何修复. `check` 坐着 双方: `checkX` 返回相同结果类型 `validateX`,仅持有 错误 `validateX` 我会先报到 再走不远了.

**粗而修之,有误而有误也.** `coerceX` 财务报告和审定财务报表 `repairX` 手执 返回该值 _财务报告和审定财务报表_ 诊断; `parseX` 手只返回值和 从不失败。 强制移动一个已经正确但写入 类型错误; 修复还替换了一个值 : 不能被强迫, 并报告验证人自己的错误 作为修复.

也就是说 `repairX` 自动修正工具,而不是更严格的验证器。 它接受 文档 `validateX` 拒绝( 缺少所需的名称获得一个; 未知) `enum` 值成为第一个成员),只接受 `valid` 带空 `repairs` 给出准确的判决 `coerceX` 给。 一个空的 `repairs` 独自一人 不够:文件也无一可修复 `valid: false`。拒绝错误的配置,使用 `coerceX`交出一个固定的, 使用情况 `repairX`。 。 。 .

**修复大型文件.** `repairX(input, options?)` 选择 对象( 一个赤色的字符串仍然读作基础路径) :

| 选项 | 默认 | 它会做什么 |
| :-- | :-- | :-- |
| `path` | `''` | 贾森 每个报告路径的指针根植于 |
| `inPlace` | `false` | 在输入上指定和删除,而不是复制容器 |
| `coerce` | `true` | 移动错误类型所写的scalar(`"5"` 下级 `integer`修复前;关闭后,按计划价值修复并报告 |
| `refs` | `true` | 后续实例 `$ref`s 位于参考计划选择的位置(以下) |
| `skipRefs` | `[]` | 指针前缀( e)`'#/components/'`其目标 根计划已经走; 仍然解决,不再走 |
| `onRef` | —— 说 | `(value, path, typeId) => boolean | void`,每个选择 `$ref`· ; `false` 别管它了 |
| `maxDepth` | `512` | 所报告位置的深度(`maxDepth`而不是走着 |
| `maxWork` | `10_000_000` | 在行走停止前参观的集装箱(`maxWork`(中文(简体) ) |
| `memo` | `false` | 在每个计划上行走每个对象——用于带有共享或循环子树的内相图 |
| `finite` | `false` | 拒绝 `NaN` 和数报的无限 |
| `plainObjects` | `false` | 只接受普通对象,并删除自己的对象 `__proto__` 键 |

当计划中的每个定义都是从 `type`, (中文(简体) ), `enum`, (中文(简体) ), `const`, (中文(简体) ), `properties`, (中文(简体) ), `required`, (中文(简体) ), `additionalProperties`, (中文(简体) ), `patternProperties`, (中文(简体) ), `items`, (中文(简体) ), `$ref`, (中文(简体) ), `if`编号 :`then`编号 :`else` 财务报告和审定财务报表 `allOf` - 附加说明,和分级 例如 `minLength`, (中文(简体) ), `pattern`, (中文(简体) ), `minimum`, (中文(简体) ), `anyOf`, (中文(简体) ), `oneOf` 或者说 `not`, (中文(简体) ), 被问及验证人自己对位置的测试.. `repairX` 是一个 单次通行证:检查并修复每个位置的位置,一个 `if` 实值 根据实际值评估,将构建缺失的必需对象 与所需子女(在递归定义上达到极限深度) 错误直接进入一个阵列,只有当某物被构建时它们才会被构建路径 报告。 有效文件本身不会被复制。 在24 MB 上 捆绑的 OpenAPI 文档远远低于百毫秒(`bun --conditions development scripts/bench-repair-walk.ts`) (中文(简体) ). 其它关键字保存 验证和修复环路,这符合 `path`, (中文(简体) ), `inPlace` 财务报告和审定财务报表 `coerce` 财务报告和审定财务报表 扔出只步选项(`skipRefs`, (中文(简体) ), `onRef`, (中文(简体) ), `maxDepth`, (中文(简体) ), `maxWork`, (中文(简体) ), `memo`, (中文(简体) ), `finite`, (中文(简体) ), `plainObjects`而不是悄悄地放下警卫.

两份计划说明指导它. `"x-repair": "drop"` ——和a `false` 计划.. 删除一个失败位置, 而不是写入默认: 未知的密钥 `additionalProperties: false`,在 `items: false`页:1 滴入标记属性. `"x-repair": "ref"` 打开参考计划 实例 `$ref` 如下: 在写职位上 `{ if: { type: object, required: [$ref] }, then: Reference, else: T }`,则 `$ref` 在根文档中以 JSON 指针解决(拥有属性) 目标作为该位置的类型加以检查和修复 目标自身路径出错. 每个目标都走过一次 每一个类型,链 周期;未解决的周期报告为 `unresolvedRef` 从未创造过.

**`parseX` 赞同 `coerceX`。 。 。 .** 无论何处 `coerceX` 接受文档 强迫 `parseX` 返回非常相同的值——通过联盟,a `allOf`,一个 `if`页:1 `$ref`,包括复发——它只修复什么 `coerceX` 将 已经拒绝了。 一个差别测试针 比随机计数。 为了到那里, 一个自有树的定义 `anyOf`编号 :`oneOf`编号 :`allOf`编号 :`if`编号 :`not` 携带一个 准确测试( e)`matchesX`和强迫行走`coerceXInput`在它的前面 修补分解器 这样一个定义都包含着它们 A 类 没有梳理器的图案 完全照着它常做的来,一个和它们一起 发布更多 — 大约是大型 OpenAPI 文档的两倍的解析器代码 对每个定义的准确意见都花了多少时间 A 类 `strict` 或者说 `stripUnknown` 解析器没有 `coerceX` 同意,并且保持不变.

`parse` 财务报告和审定财务报表 `parseStrict` 在两个合同下是同一个函数名称,所以 要求两者都是错误而不是沉默的选择.

### 离开Ajv

`coerceX` 用于替换 Ajv 编译为 `{ allErrors: true, coerceTypes: true }`,每个计数都更好:答案、速度和 输入的安全.

**它只接受计划所接受的.** 任何东西 `coerceX` 手还原为 无效, `validateX` 刚刚接受, 和差别模糊 随机 计划 `anyOf`, (中文(简体) ), `oneOf`, (中文(简体) ), `allOf` 财务报告和审定财务报表 `if`编号 :`then`编号 :`else` 检查每个 被接受的文件反对Ajv 不胁迫。 如果两者不同,它 目的为:

-   **`null` 从来没有被胁迫**无论朝哪个方向,都是不同的 你会遇到的最多: 在一个真实的配置中, 几乎每个Ajv的案件 已接受,并 `coerceX` 没有。 Ajv 读到 `null` 作为 `""`, (中文(简体) ), `0` 或者说 `false` (单位:千美元) 字符串、数字或布尔字段,并读出 `null`A级 `null` 通常表示"没有设定",而将其变成一个真正的值会抹去这一点. 给 转到写入的验证器,验证器拒绝.
    
    切换前, 请检查您的呼叫者对一个被拒绝的文档做了什么 。 如果一个 将拒绝视为缺席(返回) `undefined`,倒回到默认, 单人 `null` 在一个街区的深处 让整个街区消失 错误。 Ajv的胁迫曾经隐藏这一点. 要么让计划说 `null` 实值 允许( e)`type: ['string', 'null']`),丢出 `null`s 在验证前, 或有 调用者显示错误而不是丢弃值.
    
-   **只有干净的数字成为数字.** `" "`, (中文(简体) ), `" 1 "`, (中文(简体) ), `"0x10"`, (中文(简体) ), `"Infinity"` 财务报告和审定财务报表 `"1."` 拒绝。 Ajv把它们变成 `0`, (中文(简体) ), `1`, (中文(简体) ), `16`一个值 JSON 无法坚守,而且 `1`。 。 。 . `"007"` 财务报告和审定财务报表 `"1e3"` 仍然被胁迫.
    
-   **在工会中,一个已经匹配的分会获胜.** Ajv 胁迫 首个会取值的分支. 鉴于 `anyOf: [{ type: 'string' }, { const: false }]`,Ajv转弯 `false` 输入 `"false"`· ; `coerceX` 保留 `false`。 。 。 . 当没有分支匹配成文时,每个分支会以自己的方式强制值 并且只有在接受结果的每一个分支都同意的情况下,才会得到结果. 两种不同的读取让验证者单独报告值,所以 分行的顺序是永远不变的.
    
-   **一个失败的分支 留下什么.** Ajv 强迫到位 尝试每个分支,所以在 `oneOf: [{ type: 'integer' }, { type: 'string' }]` 转了 `0` 输入 `"0"` 在尝试字符串分支时,看到两个匹配 拒绝有效文件. `coerceX` 接受 `0` 原文如上.
    
-   **强制令每个应用者.** 斯卡拉人被胁迫通过 `$ref`, (中文(简体) ), `allOf` (每个子母依次), `if`编号 :`then`编号 :`else` (转入) `then` 当 数值匹配 `if`, (中文(简体) ), `else` 和连结的分枝.
    

**它从来不触及输入.** Ajv 强迫设置, 所以一个打电话者保持它的 文档必须先复制它. `coerceX` 返回共享的新值 所有它没有触及, 或输入本身 当不需要强迫.

**投入必须生存的地方更快.** 首先反对Ajv克隆,所以 两者都留下打电话者的证件(`bun run bench:validators:coerce`,或 `bench:validators:coerce:node`:

| 计划 | 运行时间 | 有效输入 | 需要强制 | 不能强迫 |
| :-- | :-- | :-- | :-- | --: |
| 小( 4个字段) | 阿宝 | 5.4× (中文(简体) ) | 1.7× (中文(简体) ) | 1.5× (中文(简体) ) |
| 小( 4个字段) | 节点 | 9.9× (简体中文) | 2.1× (中文(简体) ) | 2.2× (中文(简体) ) |
| 顺序( 已识别 + 数组) | 阿宝 | 11× (中文(简体) ) | 1.6× (中文(简体) ) | 1.9× (中文(简体) ) |
| 顺序( 已识别 + 数组) | 节点 | 8.4× (中文(简体) ) | 1.8× (中文(简体) ) | 2.2× (中文(简体) ) |
| 平发 | 阿宝 | 19× (中文(简体) ) | 1.4× (中文(简体) ) | 3.0× (中文(简体) ) |
| 平发 | 节点 | 36× (中文(简体) ) | 1.6× (中文(简体) ) | 3.1× (中文(简体) ) |
| 配置(通过 `$ref`(中文(简体) ) | 阿宝 | 7.2× (中文(简体) ) | 1.7× (中文(简体) ) | 3.7× (中文(简体) ) |
| 配置(通过 `$ref`(中文(简体) ) | 节点 | 5.2× (中文(简体) ) | 1.5× (中文(简体) ) | 4.6× (中文(简体) ) |

每个细胞的速度是多少倍 `coerceX` 比Ajv在同一输入, 每台发动机在自己的过程中定时(Bun 1.3.11,Node 22.22,Linux x64). A 类 有效文件是常见的,也是最大的空白: `coerceX` 用这个回答 `isX` 直接把输入拿回来,不要走. `isX` 正在建设 无事——没有错误,没有路径——在第一次失败时止步,回答: `$ref` 与目标自己的 `isX`; 它召唤 `validateX` 只是为了一个计划 折为常. 在有效输入时, Ajv 重写任何内容, 因此它可以 并且没有克隆人的时间; `coerceX` 还在前面的这些 计划,用1.2-3.3xx, 但不是每个: 在一个庞大的 工会重的文件中 呼叫者让Ajv胁迫到位,Ajv可以轻而易举地领先. 这个 上面的空白是克隆人,所以它是真实的 在那里呼叫者不能让Ajv 变异其入. 配置大小写是形状 `--coerce` 已存在, 用于: 每个可强制的平板 在工会内部 `$ref`,每个工会分支都通过 指定函数,而不是每个调用时建立的关闭.

错误不同 一种方式值得知道 如果你的关键诊断 `path + keyword + params`页:1 `additionalProperties` 出错点 **地点 未申报的密钥** (单位:千美元)`/readme/example_requests`Ajv 指向对象的地方 拿着`/readme`) (中文(简体) ). `params.additionalProperty` 将两个键都命名.

* * *

## API 密码

### `generate(rootSchema, rootTypeName, options?)`

| 参数 | 类型 | 默认 | 说明 |
| :-- | :-- | :-- | :-- |
| `rootSchema` | `JSONSchema` | —— 说 | 取根相会. `$ref` 财务报告和审定财务报表 `$dynamicRef` 递归解决. |
| `rootTypeName` | `string` | —— 说 | 根类型的名称(例如:. `"Config"`) (中文(简体) ). |
| `options.modes` | `Mode[]` | `['types', 'guard', 'validate']` | 哪个切入点可以发射. 默认为只读;任何重写文档的都是选入. |
| `options.typeSuffix` | `string` | `''` | 每页后缀 `$ref`\- 来源类型名称。 根名无相. |
| `options.schemas` | `Record<string, unknown>` | —— 说 | 您已经装入的文档, 由 URI 键入 a `$ref` 叫他们名字. |
| `options.unknownKeys` | `'count-keys' | 'count-enumerable'` | `'count-keys'` | 闭合物体的快道如何证明它没有未申报的密钥. |
| `options.formats` | `'all' | string[]` | —— 说 | 字符串 `format`s 验证符执行。 未落叶 `format` 一个注释. |
| `options.branchErrors` | `boolean` | `false` | 解释失败 `anyOf` 编号 : `oneOf` 和它明显意义上的分枝, 或者它接受的类型 当没有分枝取值的种类. |
| `options.stripUnknown` | `boolean` | `false` | 构建每个解析结果 . |
| `options.readonly` | `boolean` | `false` | 释放 `readonly` 类型成员. |
| `options.caseInsensitive` | `boolean` | `false` | 将错误的字符串规范到一个 `enum` 成员它匹配. |
| `options.helpersMode` | `'package' | 'embedded'` | `'package'` | 解析器的一半得到运行时间帮助的地方. |
| `options.helpersImportPrefix` | `string` | `'./'` | 释放的帮助导入描述符的前缀, 何时 `helpersMode` 实值 `'embedded'`。 。 。 . |
| `options.extensions` | `SchemaExtensions` | —— 说 | Schema 扩展,传递到剖析器的一半. |
| `options.importExt` | `'js' | 'ts'` | `'js'` | 每次发射的相对导入的扩展 . `'ts'` 释放上盘路径, 因此输出在节点类型剥离下运行, 没有构建步骤 . |
| `options.logWarnings` | `boolean` | `false` | 打印解析器半导体对策略的警告, 例如它无法执行的关键字 . |

回返情况: `Promise<GeneratedFile[]>` 地点 `GeneratedFile = { filename: string; content: string }`。 。 。 .

套件还出口 `ALL_MODES` (每个模式但 `parseStrict`来电的 和类型 `Mode`, (中文(简体) ), `GenerateOptions`, (中文(简体) ), `GeneratedFile` 财务报告和审定财务报表 `ImportExtension`。 。 。 .

* * *

## 输出布局

```
config.ts         the type, plus isX / validateX / coerceX / repairX
config.parse.ts   parseX, importing the type from ./config.js
validation-result.ts   the shared error and result types, and the runtime helpers
formats.ts        the format checks, only when `formats` enforces one the schema names
_helpers/         the parser's runtime helpers, only when `helpersMode` is 'embedded'
index.ts          a barrel over all of it
```

该类型生活在 `config.ts` 因为这是读者寻找的地方。 这个 解析器半个移动到 `config.parse.ts` 因为这两个生成器都命名了文件 在计划之后,他们中的一个必须让路。 只有一个 `export type Config` 在输出时,无论您要求的模式组合 测试套房通过汇编图案,在一系列图案中声称 结果是在这个repo自己的旗帜下.

请求不使用验证器模式, 且没有冲突, 所以解析器 既保留它自己的文件名, 也保留它已经编写过的文件类型, 也不保留 `validation-result.ts` 完全被释放出来 —— 仅一个解析的建筑没有 可导入其17 KiB 错误类型和运行时间帮助器.

* * *

## 更快吗?

比它包装的两个引擎? 不,它不应该是。 (Than Ajv,是的——见 [离开Ajv](https://npmcn.com/package/%40amritk/validation/#readme-moving-off-ajv). ) (中文(简体) ). 询问此软件包为一个模式, 它会发出 **准确 字节** 拥有该模式的引擎释放出——测试套接字针 模式,通过指纹,而不是读取输出。 无法使用同一代码 运行速度不同 所以这里没有运行时间 也没有 已经做了. `bun run bench` 测量它反正,三角洲徘徊在两边 运行之间为零,即进程级别差异在出现时的外观 无根本差别.

改变的只是冷淡的一面,只有你所希望的方向:

|  | (两个引擎都直接) | 之后 |
| :-- | :-- | :-- |
| 整个矩阵的代码 | 2.9 毫秒(秒) | 2.7 毫秒(秒) |
| 已发射字节 | 46.0基贝 | 45.8 基贝 |
| 文件 | 第7条 | 6个 |
| 声明 `Order` | **2个** | **1个** |
| 每模式代码源 | —— 说 | 等于或略低 |
| 每模式字节 | —— 说 | 不变 |

重要的是中间的最后一行 达到每个模式 曾经的意思是自己运行发电机 和运送两棵树一棵 计划,包括两个同类型的声明——结构 可互换,但两件事要保持步入正轨. 现在有一个.

* * *

## 相关软件包

-   [`@amritk/helpers`](https://npmcn.com/package/%40amritk/helpers) 共享类型定义和倒置表
-   [`@amritk/mjst`](https://npmcn.com/package/%40amritk/cli) ——命令行接口

* * *

## 许可证

麻省理工学院

## 常见问题

### @amritk/validation 是什么？

一个发电机表面超过Mjst的种类,验证器,胁迫器,修理器和剖析器\.

### 如何安装 @amritk/validation？

在项目目录运行 npm install @amritk/validation，或使用 pnpm add / yarn add / bun add。

### @amritk/validation 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @amritk/validation 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @amritk/validation 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=20。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @amritk/validation 可以商用吗？

@amritk/validation 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @amritk/validation 的下载量有多少？

根据 npm 官方下载统计，@amritk/validation 在 2026/10/06 – 2026/11/04 这 30 天内被下载 59,097 次，日均约 1,970 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @amritk/validation 还在维护吗？

最新版本 0\.6\.1 发布于 2026/10/23（14 天前）；至今共发布 9 个版本，其中过去 12 个月发布了 9 个；首次发布于 2026/09/22。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

