// Два отдельных типа: их различает уникальное поле (occupation / role)type User = { name: string; sex: 'm' | 'w'; age?: number; // необязателен occupation: string;};type Admin = { name: string; sex: 'm' | 'w'; age?: number; role: string;};type Person = User | Admin;const persons: Person[] = [ { name: 'Max Mustermann', sex: 'm', age: 25, occupation: 'Chimney sweep' }, { name: 'Jane Doe', sex: 'w', age: 32, role: 'Administrator' }, { name: 'Kate Müller', sex: 'w', occupation: 'Astronaut' }, { name: 'Bruce Willis', sex: 'm', age: 64, role: 'World saver' },];// Type guard: сужает Person до Admin по наличию поля rolefunction isAdmin(person: Person): person is Admin { return 'role' in person;}function logPerson(person: Person) { const additionalInformation = isAdmin(person) ? person.role : person.occupation; console.log(` - ${person.name}, ${person.age}, ${additionalInformation}`);}function getPersonWithType(person: Person) { return isAdmin(person) ? { person, type: 'admin' as const } : { person, type: 'user' as const };}
Почему person is Admin, а не boolean
Предикат типа person is Admin сообщает компилятору, что при true внутри ветки person сужается до Admin (доступно role), а в else — до User (доступно occupation). Обычный boolean такого сужения не даёт.