Код Middle Объединения и сужение спрашивают часто обновлено

Безопасный парсинг 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
  1. JSON.parse возвращает any: сразу положи результат в переменную unknown.
  2. roles.every(isRole) с guard-функцией сужает массив до Role[].

Решите в тренажёре

Редактор с автотестами прямо в браузере. Можно решить спокойно, вслух или под таймером, как на собесе.