错误信息与国际化
每个错误都有一个代码(例如 minLength)和一条信息。可以为单个规则设置信息,也可以为整个应用设置,或者加载现成的语言包。
单个规则的信息
每个 Schema 和规则的最后一个参数都是信息:
ts
string('请输入姓名')
pipe(string(), minLength(8, '密码太短'))对于 Schema(string()、object()…),信息会替换它的所有错误 —— 包括“必填”和“类型错误”。
信息中的参数
可以在花括号中使用规则参数:
ts
minLength(3, '至少 {min} 个字符') // → “至少 3 个字符”
oneOf(['a', 'b'], '请选择:{options}') // → “请选择:a, b”如果需要逻辑处理,可以传入函数 —— 它会接收参数:
ts
minLength(5, (p) => `至少需要 ${p.min} 个字符`)复数形式:“1 character”、“5 characters”
随数字变化的词形写在花括号中,用 | 分隔:先写参数,再写各个形式。形式按语言规则选择(Intl.PluralRules),语言取自语言文件中的 $locale 键:
ts
setMessages({
minLength: 'Must be at least {min} {min|character|characters} long',
});
// 1 character, 2 characters| 语言 | 形式数量 | 示例 |
|---|---|---|
| 俄语、乌克兰语 | 3:单数、少数、多数 | {n|файл|файла|файлов} |
| 英语、德语 | 2:单数、其他 | {n|file|files} |
| 中文、日语 | 1 | {n|个} 或不带形式的普通文本 |
内置的英语和俄语语言包已经使用了复数形式。如果给出的形式少于语言所需,则使用最后一个。
整个应用的信息
setMessages 修改默认文本。在应用启动时调用一次:
ts
import { setMessages } from 'tinyval';
import zh from 'tinyval/locales/zh';
setMessages(zh); // 全部使用中文
setMessages({ required: '请填写此项' }); // 覆盖部分文本单次调用的语言
setMessages 对整个应用生效。在服务端,每个请求可能使用不同的语言,此时请把信息传给调用本身 —— 不会影响其他请求:
ts
import zh from 'tinyval/locales/zh';
import en from 'tinyval/locales/en';
const locales = { zh, en };
app.post('/users', (req, res) => {
const lang = req.acceptsLanguages('zh', 'en') || 'en';
const result = validate(CreateUser, req.body, { messages: locales[lang] });
});调用时的信息可以只传一部分 —— 缺少的取自 setMessages。
字段名称 —— {label}
所有信息都可以使用 {label} 参数 —— 类似 Laravel 的 :attribute。默认是字段名(email),可以通过 label 或 labels 选项设置自定义名称:
ts
const Signup = object({
email: label(pipe(string(), email()), '邮箱'),
password: label(pipe(string(), minLength(8)), '密码'),
});
setMessages({ required: '{label}为必填项', minLength: '{label}至少需要 {min} 个字符' });
validate(Signup, { password: '123' }).errors;
// { email: '邮箱为必填项', password: '密码至少需要 8 个字符' }在客户端翻译 —— params
如果服务端不知道用户的语言,可以把错误代码和参数发送给客户端,在前端生成文本:
ts
validate(Signup, body).issues;
// [{ code: 'minLength', params: { min: 8 }, path: ['password'], message: '...' }]语言包
| 导入 | 语言 |
|---|---|
tinyval/locales/en | 英语(默认) |
tinyval/locales/ru | 俄语 |
tinyval/locales/zh | 简体中文 |
setMessages(en) 可以恢复英文文本。
如需自定义文本,可以用 npx tinyval lang zh 把语言文件复制到项目中 —— 见 自定义语言文件。
全部错误代码
| 代码 | 来源 | 英文(默认) | tinyval/locales/zh |
|---|---|---|---|
invalid | check, checkAsync | Invalid value | 无效的值 |
required | 任意 Schema 中的空值 | Required | 此项为必填项 |
string | string | Must be a string | 必须是字符串 |
number | number | Must be a number | 必须是数字 |
boolean | boolean | Must be a boolean | 必须是布尔值 |
date | date | Must be a valid date | 必须是有效的日期 |
object | object | Must be an object | 必须是对象 |
array | array | Must be an array | 必须是数组 |
literal | literal | Must be {expected} | 必须是 {expected} |
oneOf | oneOf, enumOf | Must be one of: {options} | 必须是以下值之一:{options} |
union | union | Does not match any allowed type | 不符合任何允许的类型 |
variant | variant | Unknown type, expected one of: {options} | 未知类型,允许的值:{options} |
depth | lazy | Too deeply nested (max {max}) | 嵌套层级过深(最多 {max}) |
unknownKey | 使用 unknown: 'strict' 的 object | Unknown field | 未知字段 |
minLength | 字符串的 minLength | Must be at least {min} {min|character|characters} long | 至少需要 {min} 个字符 |
maxLength | 字符串的 maxLength | Must be at most {max} {max|character|characters} long | 最多 {max} 个字符 |
length | 字符串的 length | Must be exactly {length} {length|character|characters} long | 必须为 {length} 个字符 |
min | min | Must be at least {min} | 不能小于 {min} |
max | max | Must be at most {max} | 不能大于 {max} |
integer | integer | Must be an integer | 必须是整数 |
pattern | pattern | Invalid format | 格式无效 |
email | email | Invalid email | 邮箱地址无效 |
minItems | 数组的 minLength | Must have at least {min} {min|item|items} | 至少需要 {min} 项 |
maxItems | 数组的 maxLength | Must have at most {max} {max|item|items} | 最多 {max} 项 |
items | 数组的 length、tuple | Must have exactly {length} {length|item|items} | 必须为 {length} 项 |
between | between | Must be between {min} and {max} | 必须在 {min} 到 {max} 之间 |
url | url | Invalid URL | 链接无效 |
uuid | uuid | Invalid UUID | UUID 无效 |
startsWith | startsWith | Must start with "{value}" | 必须以“{value}”开头 |
endsWith | endsWith | Must end with "{value}" | 必须以“{value}”结尾 |
includes | includes | Must contain "{value}" | 必须包含“{value}” |
unique | unique | Must not contain duplicates | 不能包含重复的值 |
minDate | minDate | Must be on or after {date} | 不能早于 {date} |
maxDate | maxDate | Must be on or before {date} | 不能晚于 {date} |
after | after | Must be after {field} | 必须晚于 {field} |
before | before | Must be before {field} | 必须早于 {field} |
inn | inn | Invalid INN | INN(俄罗斯税号)无效 |
snils | snils | Invalid SNILS | SNILS 无效 |
luhn | luhn | Invalid card number | 卡号无效 |
prohibited | prohibitedIf | Must be empty | 此项必须为空 |
file | file | Must be a file | 请选择文件 |
fileSize | file — maxSize | File must be at most {max} | 文件不能超过 {max} |
fileType | file — types | File type must be one of: {types} | 允许的文件类型:{types} |
sameAs | sameAs | Must match {field} | 必须与 {field} 一致 |
自定义信息中的未知 {参数} 会原样保留在文本中。
另请参阅
- setMessages
- ValidationError:信息如何进入异常
- 自定义规则与 Schema:自定义错误代码