TypeScript
tinyval написан на TypeScript. Тип данных выводится из схемы, поэтому отдельно описывать интерфейс не нужно.
Infer — тип из схемы
ts
import { object, string, number, optional, array, oneOf, type Infer } from 'tinyval';
const User = object({
name: string(),
age: optional(number()),
role: oneOf(['admin', 'user']),
tags: array(string()),
});
type User = Infer<typeof User>;
// {
// name: string;
// role: 'admin' | 'user';
// tags: string[];
// age?: number | undefined;
// }Поля, обёрнутые в optional без значения по умолчанию, становятся необязательными (?). С transform в тип попадает результат преобразования.
Сужение типа результата
validate возвращает объединение: после проверки valid TypeScript знает, есть ли data:
ts
const result = validate(User, input);
if (result.valid) {
result.data.name; // string
} else {
result.data; // undefined
result.errors; // Record<string, string>
}parse сразу возвращает Infer<typeof User>.
Проверка совместимости правил
Правило должно подходить к типу схемы — ошибка видна ещё до запуска:
ts
pipe(number(), minLength(2)); // ошибка: minLength работает со строками и массивами
pipe(string(), min(1)); // ошибка: min работает с числамиТипы в своих проверках
У check тип значения можно указать явно:
ts
const even = check<number>((v) => v % 2 === 0, 'Должно быть чётным');Экспортируемые типы
| Тип | Описание |
|---|---|
Schema<T> | Схема, которая возвращает значение типа T |
Infer<S> | Тип данных схемы S |
Result<T> | Результат validate |
Issue | Ошибка: { code, message, path, params } |
Message | Строка или функция (params) => string |
Options | Опции проверки: { all?, abortEarly?, messages?, labels?, maxDepth? } — см. validate |
Action<T> | Правило или преобразование для pipe |
Info | Второй аргумент check: { parent, root } |