프로그래밍프론트엔드 개발자

TypeScript에서 타입 축소(Type Narrowing)의 메커니즘을 설명하십시오. 변수의 타입을 축소하는 방법에는 어떤 것이 있으며, 이를 위해 무엇을 사용합니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

타입 축소(Type Narrowing)란 TypeScript에서 컴파일러가 특정 코드 블록 내에서 변수의 타입을 조건에 따라 보다 구체적인 타입으로 이해하는 과정입니다.

타입 축소의 일반적인 방법:

  • typeof 연산자를 통한 검사:
function example(x: number | string) { if (typeof x === 'string') { // 여기서 x: string return x.toUpperCase(); } else { // 여기서 x: number return x.toFixed(2); } }
  • instanceof를 통한 검사 (클래스용):
if (dateObj instanceof Date) { // dateObj: Date }
  • nullundefined 검사:
function print(value?: string) { if (value != null) { // value: string console.log(value.length); } }
  • "discriminant properties" (판별 속성)를 사용한 검사:
type Pet = { kind: 'dog'; woof: () => void } | { kind: 'cat'; meow: () => void }; function sound(pet: Pet) { if (pet.kind === 'dog') { pet.woof(); } else { pet.meow(); } }

TypeScript는 사용자 정의 타입 판별 함수도 지원합니다:

function isString(x: unknown): x is string { return typeof x === 'string'; }

타입 축소는 타입 검사를 더 안전하게 만들고 코드를 더 신뢰성 있게 만듭니다.

함정 질문.

일반 비교(예: ==/===)를 통해 타입 축소를 보장할 수 있습니까? 항상 작동합니까?

답변: 아닙니다. TypeScript는 간단한 비교에서 타입을 이해하지 못하는 경우가 있으며, 특히 비교가 너무 "모호"하거나 간접 변수/속성을 통해 발생하는 경우입니다. 타입 축소에는 종종 명시적인 메커니즘(typeof, instanceof, 판별 속성 및 타입 가드`)을 사용해야 합니다.

예시:

function foo(x: number | string | null) { if (x) { // x: string | number, null은 이미 불가능하지만 구체적인 타입으로 축소되지 않습니다 } }

이야기

큰 TypeScript 프로젝트에서 조건 타입 user.role == 'admin'이 데이터 타입을 축소하지 않았고, 여전히 속성 존재 여부를 확인해야 했습니다. 개발자들이 타입 축소 규칙을 과소평가하여 "Cannot read property ... of undefined" 오류가 발생했습니다.


이야기

모바일 애플리케이션에서 함수가 객체 또는 문자열을 받았습니다. 타입을 변경하는 간접 호출을 통해 축소가 이루어지지 않아, 일부 장치에서 문자열에 존재하지 않는 메서드를 호출할 때 크래시가 발생했습니다. 드문 케이스의 테스트에서 실패했습니다.


이야기

JavaScript에서 TypeScript로 코드 마이그레이션 시 자체 타입 가드 함수를 구현하지 않고, 속성 검사가 항상 타입을 축소할 것이라고 생각했습니다. 그 결과, 선택적 필드를 가진 복잡한 객체가 잘못 동작하여 런타임에서 예측할 수 없는 데이터 접근 오류가 발생했습니다.