Безопасный парсинг JSON в тип через type guard
Условие
Напиши parseUser(json: string): Result, где type Result = { ok: true; user: User } | { ok: false; error: string } и
type User = { id: number; name: string; roles: ('admin' | 'user')[]; email?: string }.
Ошибки: invalid json (не парсится), not an object (не объект или массив/null), bad <поле> для первого неверного поля в порядке id, name, roles, email (id целое число, name непустая строка, roles массив только из 'admin'/'user', email если есть, строка с @). Лишние поля в результат не копировать.
Без any и без as User: используй unknown и type guards (isRecord, isRole).
Примеры
parseUser("{\"id\":1,\"name\":\"Аня\",\"roles\":[\"admin\"],\"email\":\"a@b.ru\"}") // {"ok":true,"user":{"id":1,"name":"Аня","roles":["admin"],"email":"a@b.ru"}}
parseUser("{\"id\":2,\"name\":\"Боря\",\"roles\":[],\"isAdmin\":true}") // {"ok":true,"user":{"id":2,"name":"Боря","roles":[]}}
parseUser("{oops") // {"ok":false,"error":"invalid json"}
Как подойти
Подсказки: 2
JSON.parseвозвращаетany: сразу положи результат в переменнуюunknown.roles.every(isRole)с guard-функцией сужает массив доRole[].
Решите в тренажёре
Редактор с автотестами прямо в браузере. Можно решить спокойно, вслух или под таймером, как на собесе.
Предыдущий вопрос
isDefined: filter, который сужает тип
Следующий вопрос
Конечный автомат платежа с типами переходов