Published on

TypeScript Exercise - Solving Exercise 3

Authors
  • avatar
    Name
    hwahyeon
    Twitter

Today, I solved Exercise 3.

interface User {
  name: string
  age: number
  occupation: string
}

interface Admin {
  name: string
  age: number
  role: string
}

export type Person = User | Admin

export const persons: Person[] = [
  {
    name: 'Max Mustermann',
    age: 25,
    occupation: 'Chimney sweep',
  },
  {
    name: 'Jane Doe',
    age: 32,
    role: 'Administrator',
  },
  {
    name: 'Kate Müller',
    age: 23,
    occupation: 'Astronaut',
  },
  {
    name: 'Bruce Willis',
    age: 64,
    role: 'World saver',
  },
]

export function logPerson(person: Person) {
  let additionalInformation: string
  if ('role' in person) {
    additionalInformation = person.role
  } else {
    additionalInformation = person.occupation
  }
  console.log(` - ${person.name}, ${person.age}, ${additionalInformation}`)
}

persons.forEach(logPerson)

('role' in person) is an example of using a type guard to check whether a specific property exists in an object, allowing you to narrow down the type and write conditional logic accordingly.

In the code above, the Person type is declared as a union of User and Admin. By using a type guard condition, if the role property exists, TypeScript infers person as the Admin type; otherwise, it treats person as the User type.

Such type guards are particularly useful in scenarios like union type handling or branching logic based on the structure of API response data, where you need to separate logic depending on the structure of an object. For example, when a server returns data in multiple formats, you can safely process the data by checking for specific properties and narrowing the type accordingly.