TypeScript가 타입을 좁혀가는 법

TypeScript의 타입 좁히기와 타입이 좁혀지는 경우에 대해 알아보기

남현욱
None
4 min readJan 21, 2021

--

본 포스트는 TypeScript v4.1.2를 기반으로 하고, TypeScript Handbook v2 beta: Narrowing을 참고하여 작성하였습니다.

JavaScript 혹은 TypeScript로 프로그래밍을 할 때, 그 코드에 있는 로직을 보고 ‘이건 boolean 타입일 것이다.’ 혹은 ‘이건 절대 string 타입은 아닐 것이다.’ 라고 예측할 수 있는 상황이 있습니다.

위 코드 중 sound() 함수에서 에러가 날 만한 부분을 찾아봅시다.

14번째 줄부터 18번째 줄까지는 animal의 타입은 Dog일 것이고, 19번째 줄부터 23번째 줄까지는 animal의 타입이 Cat일 것으로 보입니다. 그래서 16번째 줄과 20번째 줄은 존재하지 않는 메서드를 사용했기 때문에 에러가 날 만한 부분입니다.

또, 25번째 줄과 26번째 줄은 Dog 및 Cat 타입에 대한 핸들링이 끝났기 때문에 어떤 타입이 나올 지 알 수 없는 상황이라 저 부분도 에러가 날 만한 부분입니다.

이렇게 결과를 추측해봤는데, 실제로 TypeScript에서 주는 결과는 어떨까요?

TypeScript는 이 상황을 알고 타입을 알맞게 추론해서 에러를 발생시켰습니다. 오늘도 프로그래머 한 명을 무사히 살렸네요 :)

이처럼 TypeScript에서는 불필요한 타입 검사를 줄이기 위해, 특정한 상황에서 더 많은 경우의 수를 가진 타입을 더 적은 경우의 수를 가진 타입으로 재정의하게 됩니다. 이 동작을 타입 좁히기(Type Narrowing)라고 합니다.

그리고, 위의 예시처럼 제한된 스코프 내에서 타입 좁히기를 발생시키는 표현을 타입 가드(Type Guard)라고 합니다.

이번 포스트에서는 TypeScript에서 타입 좁히기가 발생하는 경우에 대해 간략하게 알아보겠습니다.

타입 좁히기가 발생하는 경우

TypeScript에선 어떤 경우에 타입 좁히기가 발생할까요?

프로그램에서 실행되는 구문이나 함수가 호출되는 순서를 제어 흐름(Control Flow)이라고 하고, 이 흐름을 나타내는 구문을 제어문이라고 합니다.

제어 흐름과 제어문에 대해 더 상세한 설명은 여기를 참고해주세요.

JavaScript와 TypeScript에서 사용할 수 있는 대표적인 제어문은 아래와 같습니다.

  • 조건: if, else if, else
  • 반복: for, while
  • switch / case
  • break / continue
  • throw
  • return

TypeScript에서는 제어 흐름 분석(Control Flow Analysis)을 통해 특정한 시점에 프로그램이 어떤 상태를 가지고 있는지 알아내게 되고, 이 사실을 기반으로 특정 값의 타입을 제한할 수 있습니다.

즉, TypeScript 컴파일러에서 제어 흐름 분석을 진행할 시 타입 가드를 마주하게 되면 타입 좁히기가 발생하게 됩니다.

그럼 이 타입 가드에는 어떤 것들이 있을까요?

typeof, instanceof 연산자

가장 쉽게 타입을 알아차릴 수 있는 typeof, instanceof 연산자를 타입 가드로 사용할 수 있습니다.

맨 처음에 있는 예제는 instanceof 연산자를 타입 가드로 사용했습니다.

in 연산자

객체에 해당 프로퍼티가 있는지 체크하는 in 연산자도 타입을 식별할 수 있는 프로퍼티라면 타입 가드로 사용할 수 있습니다.

비교 구문

비교 조건과 그의 반대 조건을 합하면 모든 케이스를 커버합니다. 이 특성을 이용해 null 혹은 undefined 와 비교하는 구문을 타입 가드로 사용할 수 있습니다.

동등 연산자

JavaScript와 TypeScript에서는 서로의 타입도 일치하는지 살펴보는 엄격한 동등 연산자 === 이 있는데, 이 동등 연산자도 타입 가드로 사용할 수 있습니다.

서로소 합 타입 (Discriminated Unions)

리터럴 타입 식별자를 갖는 여러 타입이 합 타입으로 결합된 타입을 서로소 합 타입이라고 합니다.

서로소 합 타입도 타입 식별자를 체크함으로써 타입 가드로 사용할 수 있습니다.

번외: 할당

할당 구문도 아래의 케이스처럼 타입 가드로 사용할 수 있습니다.

--

--

남현욱
None

세상이 아름다워지는 것을 지향하는 프론트엔드 개발자 남현욱입니다. 휴먼스케이프에서 프론트엔드 개발을 하고 있습니다.