📢 어렵고 정석적인 개념 설명보다는 저같은 초보자도 이해하기 쉽게 정리하는 것을 원칙으로 포스팅하고 있습니다. 😄

[TypeScript] 타입 가드 is를 사용하는 이유 (vs 타입 단언)

타입 가드 is를 사용하는 이유

타입 가드의 역할은 변수가 특정 타입인지의 여부를 확인하고, 이를 확실히 한 뒤 해당 타입을 안전하게 사용할 수 있도록 하는 것이다. 주로 is...로 시작하는 함수에서 타입 가드를 많이 사용하며, 이것이 문자열인지, 숫자인지 혹은 배열인지 등의 타입을 명시적으로 하기 위해 사용된다. 예시 코드를 보면서 함께 이해하자.

function isNumber(value: any): value is number {
    return typeof value === 'number';
}

function printNumber(value: any) {
    if (isNumber(value)) {
        console.log(value + 10);
    } else {
        console.log('이것은 숫자가 아닙니다.');
    }
}

printNumber(5); // 15
printNumber('abc'); // '이것은 숫자가 아닙니다.'

isNumber(value: any)를 보면 현재 파라미터 value의 타입은 any로 아무 타입이나 파라미터 값으로 받아올 수 있게 해 놓았다. 하지만, 뒤에 value is number라고 타입 가드를 사용하여 value의 타입이 number인지 여부를 확인해 주었다.

 

value is number를 마치 타입 단언처럼 "value의 타입은 number야!"라고 해석하면 안 된다. "value가 any 타입으로 받아오지만, 만약 value 타입이 number라면 타입을 any가 아닌 number로 확정해 주겠어!"라고 해석하는 게 정확하다.

즉, 타입 가드는 타입을 정해주는 게 아니라 (컴파일러에게) 타입을 더 확실하게 알려주는 역할을 하는 셈이다.

 

타입 가드의 경우 주로 if문과 함께 사용된다. 주로 타입 가드의 경우 타입을 명시적으로 정하기 위해 사용하는 경우가 많으므로 if문과 함께 '이게 이 타입이라면... 혹은 저게 저 타입이라면...' 식으로 타입마다 다른 리턴값을 도출해 내는 함수 안에서 주로 볼 수 있다. (하나의 함수가 타입에 따라 여러 가지 값을 리턴할 경우 조건문에 타입 가드 함수를 넣는 경우가 많다. 왜냐하면 타입에 따라 다른 값을 리턴할 건데 타입이 명확하지 않으면 제대로 동작하지 않기 때문에 타입 가드로 타입을 명확히 해주는 것이다.)

 

타입 가드 is의 경우 주로 함수와 함께 사용된다. 이것을 타입 가드에서 "사용자 정의 함수를 사용한다"라고 말하며, 그 함수는 is를 사용해서 타입 가드 역할을 수행한다. (예시 코드의 isNumber 함수가 바로 사용자 정의 함수이며, 주로 이 함수는 타입을 명확히 해주는 타입 가드 역할만을 수행한다.)

 

🤔 타입 가드
타입 가드는 is 문법만 있는 게 아니다. typeof, instanceof, in 연산자 등 타입 가드 용법은 많다.
간단한 방법으로는 주로 typeof를 많이 사용한다. if (typeof value === 'number') 라고 하면, if문 안에 value의
타입은 number로 인식된다. 따라서, 타입 가드 문법은 코드의 복잡성과 요구사항에 따라 적절하게 사용하면 된다.

 

타입 단언 as를 사용하는 이유

타입 가드가 해당 값의 타입이 무엇인지 명확하게 하기 위한 장치였다면, 타입 단언은 그냥 개발자가 타입스크립트 컴파일러에게 "이 변수의 타입은 이거야!"라고 직접적으로 타입을 정하는 장치라고 생각하면 된다.

let value: any = '이것은 문자열입니다.';
let length: number = (value as string).length;
console.log(length); // 12

위의 예시 코드를 보면 변수 value는 any 타입으로 선언되어 있다. any 타입은 어떤 종류의 값이든 저장될 수 있고, 어떤 속성이든 접근할 수 있다. 따라서, value.length라고 해도 타입 에러는 발생하지 않는다.

하지만, length 속성은 string 타입에 존재하는 속성이므로 any 타입에 length를 쓰면 런타임 과정에서 에러가 발생할 수도 있으며, any 타입의 사용은 타입 안전성을 감소시키므로 타입스크립트를 사용하는 이유가 없어지게 된다.

 

따라서, length 속성을 사용하기 위해 any 타입인 value를 타입 단언 as를 이용해서 string으로 바꿔주면 컴파일러가 value의 타입을 string으로 인식하기 때문에 오류 없이 타입 안전성을 지킬 수 있게 된다.

 

1. value is number : 파라미터 value의 타입이 number라면 value 타입을 number로 확정하겠다.
2. value as number : 변수 value의 타입은 이제부터 number라고 인식해라.