Компромиссы
- Indexed access вместо re-declare sub-type.
type Role = User['role'] лучше copy-paste union — derived обновится при изменении User.
typeof arr[number] на as const array — canonical «union from list» — одно место добавить value, array и type растут вместе.
- Deep nested lookups (
A['b']['c']['d']) нечитаемы. Named intermediate (type BC = A['b']['c']) kinder следующему reader.
Итог
Prefer lookup от базового типа; as const + [number] для union из данных; промежуточные aliases для глубины.