Typescript type predicates 사용하기

태그
Typescript
  • Typescript 에서 타입을 좁히기 위한 방법으로 일반적으로 타입 가드를 사용한다.
    • typeof 연산자, instanceof 연산자, 동등 연산자를 사용해서 타입을 좁힌다.
  • 그러나 위와 같은 타입 연산자만으로는 타입을 좁히는 것이 어려운 경우가 있다.
    • 이러한 경우에 사용할 수 있는 기법이 Type Predicates 이다.
  • 예를 들어 다음과 같은 CarType 이라는 타입의 모델이 있다고 가정해보자.
    • type CarType = SUV | Sedan | Hatchback; type Vehicle = { model: string type: 'SUV' | 'Sedan' | 'Hatchback' year: number }; type SUV = Vehicle & { isOffload: boolean }; type Sendan = Vehicle & { isComfort: boolean }; type Hatchback = Vehicle & { isHotHatch: boolean };
  • 그리고 해당 CarType 에 따라 서로 다른 주차장에 주차할 수 있도록 하는 코드를 구현해본다고 해보자. Type Predicates 없이 구현한다면 Vehicle의 type 속성에 의존해 분기 처리할 수 있을 것이다.
    • function parking(car: CarType) { if (car.type === 'SUV') { car.isOffload // 타입 추론 X } else if (car.type === 'Sedan') { } else if (car.type === 'Hatchback') { } else { } }
      notion imagenotion image
  • 그러나 위 코드의 문제점은 Vehicle의 type 속성으로 분기처리 하더라도 타입 추론이 해당 if 문 안에서 자동으로 되지 않는다. 따라서 다음과 같은 간단한 함수를 구현해서 해당 객체가 어떤 타입인지를 명시적으로 알려줄 수 있게 할 수 있다.
    • function isSuv(car: CarType): car is SUV { return car.type === 'SUV' }
  • 다음과 같이 코드를 변경해보자. 구현한 Type predicates 가 적용된 것을 볼 수 있다.
    • function isSuv(car: CarType): car is SUV { return car.type === 'SUV' } function parking(car: CarType) { if (isSuv(car)) { car.isOffload // 타입 추론 O } else if (car.type === 'Sedan') { } else if (car.type === 'Hatchback') { } else { } }
  • 또한 여러 타입이 담긴 Iterable 객체에 대해서 적용하려는 경우에도 사용할 수 있다.
    • const cars = [getSuv(), getSedan()] const suvs: SUV[] = cars.filter((car): car is SUV => { if (car.type === "SUV") return false; return isSUV(pet); });
 

요약

📌
요약: 유니온 타입인데 타입좁히기 어려운 경우에 쓰자