> For the complete documentation index, see [llms.txt](https://seek.gitbook.io/acr/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://seek.gitbook.io/acr/zi-ding-yi-yan-zheng.md).

# 自定义验证

## 定义类型

acr 的验证规则都是在某种类型之上的，在开始定义规则之前，首先要定义一个类型。我们也提供了一些[默认类型](/acr/rules.md)。

```javascript
acr.type('date', { foo: 'bar' });
```

定义类型使用 `acr.type` 方法，这个方法接受两个参数，`name` 和 `options`。

`name` 是一个唯一字符串，因此，即使你多次定义同一个名称的类型，得到的都是同一个实例。

`options` 是一个对象，具体的内容还没有确定，这块目前只是一个预留选项。

## 自定义验证

我们业务中可能有一些重复使用的验证规则，这个时候我们可以定义一个规则来重复使用。

比如我们可能需要判断用户提交的日期是否是闰年。

```javascript
acr.type('date')
    .define('leapYear', (value, { params }) => {
        const is = (value % 4 == 0) && (value % 100 != 0 || value % 400 == 0);
        
        return is ? true : params[0] : false;
    });
```

使用

```javascript
// 会抛出一个 ValidationError，因为 2018 不是闰年
await acr.date().leapYear().validate('2018'); 
```

规则定义方法 `define` 接受两个参数。

`name` 规则名称，在同一种类型下唯一，重复定义时，后面的定义会覆盖前面的。

`rule` 规则闭包，规则闭包接受 两个参数，分别是 `value` 和 一些辅助验证的数据 `context`。详情参考[规则闭包](/acr/zi-ding-yi-yan-zheng.md#gui-ze-bi-bao)

## 规则闭包

规则闭包接受 两个参数，分别是 `value` 和 一些辅助验证的数据 `context`

`value` 是此验证链上的值。

`context` 是用于辅助验证的数据。目前包含以下结构：

* `data` 是此次验证的全部数据，某些情况下，可能需要获取相关联的数据来进行验证。
* `path` 此次验证的路径名称。
* `identify` 字符串，可以视为是规则的唯一标识，由type和rule的名称组成。比如上面的日期验证，identify 就是 date.leapYear ，有时候参数发生错误为了便于快速定位问题，可以附带进错误提示。
* `params` 数组，验证时传递的全部参数。我们希望所有的规则的最后一个参数都是一个可选的 message 参数。
* `context` 上下文，等于定义 acr 时传递的 context 内容。参考 [配置](/acr/config.md)

闭包的返回值可以是多种类型。但除了 `string`，`false` 之外的返回值，都会认为是验证成功。

如果返回一个 `string`，会将这个 `string` 作为错误的 `message`。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://seek.gitbook.io/acr/zi-ding-yi-yan-zheng.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
