Skip to content

错误信息与国际化 ​

每个错误都有一个代码(例如 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
invalidcheck, checkAsyncInvalid value无效的值
required任意 Schema 中的空值Required此项为必填项
stringstringMust be a string必须是字符串
numbernumberMust be a number必须是数字
booleanbooleanMust be a boolean必须是布尔值
datedateMust be a valid date必须是有效的日期
objectobjectMust be an object必须是对象
arrayarrayMust be an array必须是数组
literalliteralMust be {expected}必须是 {expected}
oneOfoneOf, enumOfMust be one of: {options}必须是以下值之一:{options}
unionunionDoes not match any allowed type不符合任何允许的类型
variantvariantUnknown type, expected one of: {options}未知类型,允许的值:{options}
depthlazyToo deeply nested (max {max})嵌套层级过深(最多 {max})
unknownKey使用 unknown: 'strict' 的 objectUnknown field未知字段
minLength字符串的 minLengthMust be at least {min} {min|character|characters} long至少需要 {min} 个字符
maxLength字符串的 maxLengthMust be at most {max} {max|character|characters} long最多 {max} 个字符
length字符串的 lengthMust be exactly {length} {length|character|characters} long必须为 {length} 个字符
minminMust be at least {min}不能小于 {min}
maxmaxMust be at most {max}不能大于 {max}
integerintegerMust be an integer必须是整数
patternpatternInvalid format格式无效
emailemailInvalid email邮箱地址无效
minItems数组的 minLengthMust have at least {min} {min|item|items}至少需要 {min} 项
maxItems数组的 maxLengthMust have at most {max} {max|item|items}最多 {max} 项
items数组的 length、tupleMust have exactly {length} {length|item|items}必须为 {length} 项
betweenbetweenMust be between {min} and {max}必须在 {min} 到 {max} 之间
urlurlInvalid URL链接无效
uuiduuidInvalid UUIDUUID 无效
startsWithstartsWithMust start with "{value}"必须以“{value}”开头
endsWithendsWithMust end with "{value}"必须以“{value}”结尾
includesincludesMust contain "{value}"必须包含“{value}”
uniqueuniqueMust not contain duplicates不能包含重复的值
minDateminDateMust be on or after {date}不能早于 {date}
maxDatemaxDateMust be on or before {date}不能晚于 {date}
afterafterMust be after {field}必须晚于 {field}
beforebeforeMust be before {field}必须早于 {field}
inninnInvalid INNINN(俄罗斯税号)无效
snilssnilsInvalid SNILSSNILS 无效
luhnluhnInvalid card number卡号无效
prohibitedprohibitedIfMust be empty此项必须为空
filefileMust be a file请选择文件
fileSizefile — maxSizeFile must be at most {max}文件不能超过 {max}
fileTypefile — typesFile type must be one of: {types}允许的文件类型:{types}
sameAssameAsMust match {field}必须与 {field} 一致

自定义信息中的未知 {参数} 会原样保留在文本中。

另请参阅 ​