Comments 4
Спасибо большое за коментарий, и ваш ник прям как никогда подходит к содержанию комментария.
Постараюсь придумать названия получше
Реквестую симбиоз с подходом вот из этой библиотеки: https://www.npmjs.com/package/ts-optchain
А именно, иметь не только валидаторы, но еще и возможность доступаться к свойствам через цепочку, которая может содержать undefined-ы. Чтобы не писать
obj.a && obj.a[0] && obj.a[0].b && obj.a[0].b.c || “default”
везде, а писать что-то типа obj.a[0].b.c(“default”) и obj.a[0].b.c() (бросает исключения с детальным описанием, что именно и где не хватало) и иметь это все TS-строготипизированно.
Еще было бы круто генерировать детальные отладочные сообщения при исключениях автоматически, чтобы в них включался исходный json, а не только имя поля (или путь к полю), где произошла ошибка. Чтобы не писать везде if-ы.
Спассибо за комментарий и за предложения. Что-то на подобие pathOr
из ramda
.
На самом деле на практике никто не добавляет сообщения об ошибках в таком виде. Это просто была демонстрация, того, куда идут эти сообщения об ошибках после валидации(раньше в глобальный объект, а теперь в локальный переданный через параметр). Просто данный способ(для каждой валидации своё объяснения) легче всего понять, поэтому именно он и был использован.
Данная статья концентрировалась на архитектурных ошибках и их исправлениях.
В самой библиотеке есть возможность определить объяснения для всех ошибок с помощью поля defaultExplanation
в функции quartet(settings). Но данная функция была определена изначально, именно поэтому она не попала в статью про ошибки архитектуры.
Чтобы не писать объяснения для всех валидаций — можно написать одну функцию, которая будет применена ко всем ошибкам — и возвращает уникальное описание. В библиотеке предусмотрены два дефолтных конструктора валидаторов (full и obj).
import { obj as v } from 'quartet' // obj has object explanation of the errors by default
const checkPerson = v({
name: v.string,
brothers: v.arrayOf(v.string),
sisters: v.arrayOf(v.string),
age: v.number
})
v.explain(checkPerson)({
name: 'Andrew',
brothers: ['Bohdan', 'Taras', 'Yuri', 'Alex'],
sisters: null, // invalid value
age: 22
})
/*
returns [
{
value: null,
schema: { type: 'ArrayOf', innerShema: { type: 'String' } },
parents: [
{
key: 'sisters',
parent: {
name: 'Andrew',
brothers: ['Bohdan', 'Taras', 'Yuri', 'Alex'],
sisters: null, // invalid value
age: 22
},
schema: {
name: v.string,
brothers: v.arrayOf(v.string),
sisters: v.arrayOf(v.string),
age: v.number
}
}
]
}
]
*/
Мои грабли: из грязи в князи