8.1 타입 단언 (Type Assertion)

8.1.1 타입 단언이란?

타입 단언은 타입스크립트가 타입 추론을 예상과 다르게 추론했을 때 사용합니다. 개발자가 해당 값의 타입을 확신할 때 명시적으로 지정해 컴파일러에게 “이 값은 이 타입이야” 라고 알려주는 것과 같습니다. 대표적인 타입 단언 방법 두 가지를 알아보겠습니다.

1) as 단언

기본적인 as 연산자를 사용해 Value as <Type> 형식으로 타입 단언을 할 수 있습니다.

let one: unknown = 'hello';
let oneLength : number = ((one as string).length);
console.log(oneLength); // 5

위의 코드에서 one 변수의 타입이 unknown이지만 타입 단언을 사용해 string 타입으로 단언해주면 one 변수의 문자열 길이를 출력할 수 있습니다.

2) <> 단언

<Type>Value 형식을 사용해 타입 단언을 할 수 있습니다.

let one: unknown = "hello"; 
let oneLength: number = (<string>one).length;
console.log(oneLength); // 5

먼저 살펴봤던 예제 코드를 <>연산자를 사용해 <string>one 형태로 타입을 지정할 수 있습니다. 하지만 React의 .tsx 파일에선 구문 분석에 어려움을 초래할 수 있으므로, 타입 단언을 위해 <>대신 as 연산자를 사용하는 것을 권장합니다.

<aside> 💡 타입 캐스팅(Type Casting)과 타입 단언은 어떤 점이 다를까요?

다른 언어에서 사용되는 비슷한 개념인 타입 캐스팅(Type Casting)와 비교해 보면 사용 방식과 특정 값이 특정 타입임을 컴파일러에 알려주는 점에서 비슷하지만 작동 방식에서 차이가 있습니다.

타입 단언은 런타임에는 아무런 영향을 주지 않기 때문에 실행 에러는 미리 방지하지 못하고, 오직 컴파일 타임에서만  타입을 변화시켜 타입 에러만 해결할 수 있고, 실제 데이터의 타입을 변환시키지 않습니다.

타입 캐스팅은 런타임과 컴파일 타임에서 실제 데이터의 타입을 변경시킨다는 점에서 타입 단언과 차이를 알아볼 수 있습니다.

</aside>

8.1.2 타입 단언 규칙

이번 절에서는 타입 단언의 규칙에 대해 알아보겠습니다. 타입 단언을 사용할 때는 값과 타입 간의 관계가 중요한데, 이는 부모-자식 관계로 설명될 수 있습니다. Value as <Type> 형식을 가질 때, Value는 Type의 슈퍼 타입(부모 타입)이거나 서브 타입(자식 타입)이어야 합니다. 따라서 이 두 가지 조건 중 하나는 반드시 만족해야 합니다.

let one = 'hello' as number; // Error
let two = 100 as string; // Error
let three = true as object; // Error

위의 코드에서는 Value와 Type의 관계가 서로 호환되지 않아 에러가 발생합니다. 이를 호환 가능한 타입으로 고치면 아래와 같습니다.

let one = 'hello' as unknown; // OK
let two = 100 as unknown; // OK
let three = true as never; // OK

하지만 기존 타입과 호환되지 않는 타입으로 단언할 필요가 있는 상황이 발생합니다. 이 경우 다중 단언을 사용해 나타낼 수 있습니다. 다중 단언은 목차 8.1.5에서 자세히 알아보도록 하겠습니다.